Skip to main content

zymtrace-anchored-query

Reusable wrapper for the knowledge-base-first SQL pattern, adapted to the zymtrace ClickHouse profiling backend. Operator names the metric / question / time range. Skill anchors the `zymtrace_profiling.events` schema first (DESCRIBE + label-value + cardinality probes), derives the safe narrow SQL, runs it via `kubectl port-forward` + `curl -X POST`, and saves the raw payload to a provenance-bearing bundle per the perf-lake-contract. Workload-agnostic. The ClickHouse cousin of `prometheus-anchored-query`. Triggers on "zymtrace anchored query", "clickhouse anchored query", "zymtrace query", "save zymtrace payload", "anchored zymtrace", "anchored clickhouse", or any combination of "zymtrace / clickhouse / profile" with "anchored / safe / provenance / query / saved-payload".

소스 정보

저장소
cfregly/gpu-perf-tune
최근 소스 활동
2026년 8월 16일 20:38
감지된 SKILL.md 언어
영어
스타
3
포크
0

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
zymtrace-anchored-query
license
MIT
compatibility
Requires a skills-compatible agent and a POSIX shell with the commands named by the workflow.
metadata
{"last-validated":"2026-05-24"}
description
Reusable wrapper for the knowledge-base-first SQL pattern, adapted to the zymtrace ClickHouse profiling backend. Operator names the metric / question / time range. Skill anchors the `zymtrace_profiling.events` schema first (DESCRIBE + label-value + cardinality probes), derives the safe narrow SQL, runs it via `kubectl port-forward` + `curl -X POST`, and saves the raw payload to a provenance-bearing bundle per the perf-lake-contract. Workload-agnostic. The ClickHouse cousin of `prometheus-anchored-query`. Triggers on "zymtrace anchored query", "clickhouse anchored query", "zymtrace query", "save zymtrace payload", "anchored zymtrace", "anchored clickhouse", or any combination of "zymtrace / clickhouse / profile" with "anchored / safe / provenance / query / saved-payload".
allowed-tools
Bash(kubectl:port-forward,*) Bash(kubectl:get,*) Bash(curl:*) Bash(jq:*) Bash(sha256sum:*) Bash(date:*) Read Write
# zymtrace-anchored-query ## Purpose Make ad-hoc ClickHouse queries against the [zymtrace](https://docs.zymtrace.com) profiling backend **safe by default** by wrapping the "anchor labels in the schema FIRST, then run the query" discipline as a reusable skill. Saves the raw payload to a provenance-bearing bundle so future queries can replay the same shape, and so the perf-lake-contract is honored without operator effort. This skill exists because the `zymtrace_profiling.events` table on a busy cluster holds tens of millions of rows per day across every profiler-enabled namespace. An SQL query that forgets to bound `timestamp` or `pod_name LIKE '...'` returns a full-table scan that overloads ClickHouse and starves real-time ingest. The anchor-then-query pattern works for arbitrary profiling questions. This skill makes it agent-routable. [`prometheus-anchored-query`](../prometheus-anchored-query/SKILL.md) is the Prometheus version of the same pattern. Use this when the question targets profiling data (CPU on-cpu samples, GPU cuda kernel samples, stack-traces, function-resolution lookups). Use the Prometheus skill when the question targets time-series cluster metrics. ## When to use - Operator has a profiling question that maps to a ClickHouse query but doesn't know the exact `pod_name` pattern, time-window, or `event_kind` to use yet. - Operator wants to save a zymtrace payload to disk with provenance (for evidence bundles, profile-findings write-ups, share-with-team artifacts, or feeding the optional `kernel_class_gpu_pct` + `cpu_spinpoll_pct` fields into the [`inference-perf-baseline-bridge`](../inference-perf-baseline-bridge/SKILL.md) schema). - Operator wants to confirm a `pod_name` LIKE pattern matches the expected pod set + that the time window has enough samples to be statistically useful before running a full top-N query. Do **not** use this skill for: - Already-vetted profile queries - just run the SQL directly via `curl -X POST 'http://localhost:9123/' --data-binary @<query.sql>`. - Live UI exploration - the zymtrace web UI has its own flamegraph/timeline views. This skill is for headless reproducible queries. - Cross-tenant queries - every example here scopes to a single `pod_name LIKE` pattern. Cross-tenant exploration belongs to the zymtrace UI or the zymtrace MCP's pattern-recognition tools. ## Example prompts - "What are the top 25 hottest CUDA kernels in `basic-inference` pods over the last 5 minutes?" - "Save the on_cpu hot-Python-callers query for `glm-inference` between 16:00 and 16:30 UTC." - "Did `shm_broadcast.py` CPU time in the `glm-inference` pods drop after we set VLLM_USE_SHM_BROADCAST_BLOCKING=1? Compare the last 30 minutes against the window before the change." - "Get me the kernel-class breakdown for the `kimi-inference` pods during the perf-bench window I just ran so I can fill `kernel_class_gpu_pct` in the perf-baseline bundle." - `/zymtrace-anchored-query --question "top-25 cuda kernels for basic-inference pods, last 5 min" --time-range "now-5m..now"` - `/zymtrace-anchored-query --pod 'basic-inference%' --event-kind cuda --window '<start-UTC>..<end-UTC>' --top 25` ## Prerequisites 1. **Cluster context active** - `kubectl config current-context` returns the cluster running zymtrace. 2. **zymtrace backend deployed** - `kubectl -n zymtrace get pods -l app=zymtrace-clickhouse` shows at least one Running pod. 3. **Operator question or pod+kind+window** - one of: - Free-form question (skill derives `pod_name` pattern + `event_kind` + window via schema introspection). - Explicit `--pod <LIKE-pattern> --event-kind <cuda|on_cpu> --window <UTC-range>`. 4. **Time window** - `--time-range "now-Nm..now"` or absolute UTC range. Default `now-5m..now`. Queries with no `timestamp` bound are refused. 5. **`PROFILE_AND_OPTIMIZE_REPO_ROOT`** for the bundle path (falls back to `${PWD}/zymtrace-bundles/<run-id>/`). ## Interaction style Iterative. The whole point of the skill is the "anchor first, then query" discipline. Pause after the schema-anchor call to surface the proposed SQL before running it. ## Workflow ### Phase 0: resolve the question If operator provided a free-form question, restate the question + the proposed `pod_name` LIKE pattern, `event_kind`, and time window in one sentence. Get confirmation. If operator provided explicit pod + kind + window, proceed. ### Phase 1: schema + label anchor Start the port-forward if not already running: ```bash # Idempotent: skip if a port-forward to svc/zymtrace-clickhouse is already up on 9123. if ! curl -fsS -o /dev/null -m 2 'http://localhost:9123/ping'; then nohup kubectl -n zymtrace port-forward svc/zymtrace-clickhouse 9123:8123 \ > /tmp/zt-ch-pf.log 2>&1 & disown sleep 3 fi ``` Probe the schema for the table the query will hit (default `zymtrace_profiling.events`): ```bash curl -fsS -X POST 'http://${CH_USER}:${CH_PASSWORD}@localhost:9123/' \ --data-binary 'DESCRIBE TABLE zymtrace_profiling.events FORMAT JSON' \ > /tmp/zt-schema-anchor.json ``` Then sanity-check cardinality of the proposed selector before running the full top-N query: ```bash curl -fsS -X POST 'http://${CH_USER}:${CH_PASSWORD}@localhost:9123/' \ --data-binary " SELECT count() AS rows, uniqExact(pod_name) AS pods, min(timestamp) AS first_ts, max(timestamp) AS last_ts FROM zymtrace_profiling.events WHERE pod_name LIKE '<pattern>' AND event_kind = '<kind>' AND timestamp >= '<start>' AND timestamp <= '<end>' FORMAT JSON " ``` The cardinality probe response tells us: - Whether the selector matches **any** rows (catches typos in `pod_name` LIKE patterns immediately). - The exact `pod_name` set the query will scan (catches accidental cross-pod scope). - The actual `timestamp` range that has data (catches misaligned windows - e.g. a window anchored on the bench's scheduled start when the run actually began and ended a few minutes later, a common first-pass mistake). - The sample count (so the operator can decide if the window is too short to be statistically meaningful - <1000 samples is typically not enough). If `rows = 0`: do NOT immediately conclude "no signal". Zymtrace data is not instantaneous - rank two causes in this order: 1. **Ingest lag (transient).** If the pod/window are freshly-run (the bench just ended), zymtrace may not have flushed to ClickHouse yet - it flushes **asynchronously** (~seconds-to-minutes). **Wait for the flush and re-run the cardinality probe** for the freshest data before concluding. A simple poll (mirrors [`scripts/zymtrace-ingest-wait.sh`](../../../../scripts/zymtrace-ingest-wait.sh)): ```bash for i in $(seq 1 "${ZYM_INGEST_MAX_ATTEMPTS:-6}"); do rows=$(curl -fsS -X POST 'http://${CH_USER}:${CH_PASSWORD}@localhost:9123/' \ --data-binary "<the cardinality probe SELECT ... FORMAT JSON>" | jq -r '.data[0].rows') [ "${rows:-0}" -gt 0 ] && break sleep "${ZYM_INGEST_WAIT_SEC:-20}" # requery for the freshest data done ``` 2. **Wrong selector / window.** If it STAYS 0 past the flush window, the `pod_name LIKE` pattern or `[start,end]` doesn't match - re-query by `host=<node>`+window (the hash-suffixed pod-name filter often reads empty when the host filter returns frames) and confirm the window. Per the fail-fast rationale in [`server/docs/zymtrace-query-hygiene.md`](../../server/docs/zymtrace-query-hygiene.md), running the top-N on an empty result would look like "no signal" when it is really either ingest lag (requery) or a wrong selector (fix it) - never silently proceed. If `rows > 10_000_000`: refuse. The selector is too broad. Narrow the time window or `pod_name` pattern. ### Phase 2: emit the SQL Construct the narrow SQL using only schema-anchor-confirmed labels and the operator's `--time-range`. The SQL **must** include all three bounds: ```sql WHERE pod_name LIKE '<pattern>' AND event_kind = '<kind>' AND timestamp >= '<start>' AND timestamp <= '<end>' ``` Print the proposed SQL back: ```text Proposed SQL: <full query> Anchor: pod_name LIKE '<pattern>', event_kind = '<kind>' Time range: <start> .. <end> Expected rows scanned: ~<from cardinality probe> LIMIT clause: <N rows> (default 25) ``` Ask: "Run this query?" Do not auto-advance. ### Phase 3: run + save After confirmation, run the query via curl + save the raw response: ```bash RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)" BUNDLE_DIR="${PROFILE_AND_OPTIMIZE_REPO_ROOT:-${PWD}}/experiments/artifacts/zymtrace-bundles/${RUN_ID}" mkdir -p "${BUNDLE_DIR}" cat > "${BUNDLE_DIR}/query.sql" <<'EOF' <the exact SQL from Phase 2> EOF curl -fsS -X POST 'http://${CH_USER}:${CH_PASSWORD}@localhost:9123/' \ --data-binary "@${BUNDLE_DIR}/query.sql" \ -H 'X-ClickHouse-Format: JSON' \ -o "${BUNDLE_DIR}/response.json" sha256sum "${BUNDLE_DIR}/query.sql" "${BUNDLE_DIR}/response.json" \ > "${BUNDLE_DIR}/sha256sums.txt" ``` Save the bundle layout (parallels `prometheus-bundles/<run-id>/` for consistency): ``` ${PROFILE_AND_OPTIMIZE_REPO_ROOT}/experiments/artifacts/zymtrace-bundles/<run-id>/ SOURCE.md # operator + question + cluster + UTC-ts + git SHA query.sql # the exact SQL run query.json # the curl request shape (URL, headers, body-ref) response.json # the raw ClickHouse response (saved verbatim) summary.md # human-readable: row count, top-5 by pct, anchor recap schema-anchor.json # the DESCRIBE + cardinality-probe responses (provenance) sha256sums.txt # query.sql + response.json sha256 ``` ### Phase 4: report Print: - **Row count** + **scanned-rows count** (sanity check: did we get the cardinality the anchor predicted?). - **Top 5 rows** of the response (highest `pct` or `total_samples`). - **Bundle path** for the saved payload. - **Cross-link** to [`inference-perf-baseline-bridge`](../inference-perf-baseline-bridge/SKILL.md) if the operator's question maps to a `kernel_class_gpu_pct` or `cpu_spinpoll_pct` field (it usually does - that's the canonical consumer of this skill's output). ## Kernel-class bucketing (appendix) The [`inference-perf-baseline-bridge`](../inference-perf-baseline-bridge/SKILL.md) schema's `kernel_class_gpu_pct` field is derived by bucketing kernel names from this skill's GPU-side response. The canonical regex set covers the kernel classes that dominate FP8 MoE serving on B200-class hardware: | Bucket key | Regex on `kernel` (func_name) | What it catches | | --- | --- | --- | | `fp8_bmm` | `^bmm_(E4m3|Bfloat16)_E4m3E4m3` OR `sm100_fp8_gemm` OR `deep_gemm::sm100_fp8` | FP8 block-quantized batched matmul (the dominant compute on B200 Kimi/DeepSeek) | | `tp_all_reduce` | `multimem_all_reduce_kernel` OR `trtllm_allreduce` OR `oneshot_lamport` | Tensor-parallel all-reduce kernels (both PyTorch CUDASymmetricMemoryOps + flashinfer paths) | | `cuda_event_sync` | `cudaEventSynchronize` OR `cuda-sync` | Host-side CUDA event sync (sign of cudagraph coverage gaps) | | `mla_attention` | `fmhaSm100fKernel` OR `cute_flash_fwd_sm100` OR `mla_attention` | DeepSeek-V3-style MLA attention (Q576/V512 paged-KV) | | `moe_routing_finalize` | `moe::dev::(routing|finalize|activation)` | DeepSeek MoE routing + finalize kernels | | `per_token_group_quant` | `per_token_group_quant_8bit` | Block-FP8 activation quantization (group_size=128) | Apply the regex against `kernel` in the GPU response, sum the `pct` per bucket, leave classes outside this set under arbitrary `<other-class>` keys (e.g. `nvjet_trt_llm`, `d2d_memcpy`, `elementwise_misc`). ## Full-context reporting (no bare numbers) Per `docs/METHODOLOGY.md` "Full-context reporting": every number this skill emits (throughput, latency, TPOT/ITL, BW, %SoL, speedup, efficiency, goodput, acceptance rate, scaling efficiency, thermal/failure rate - whatever it reports) MUST carry its full measurement-context descriptor, and every comparison MUST be matched on it. A bare number is a defect - it cannot set a default, ship a config, or appear in a report. - **Identity:** model (+HF path), hardware (exact ceiling token `GB300`/`B200`), quant, kv-cache dtype. - **Parallelism:** TP, DP (replicas), PP, EP, parallel_strategy. - **Serving cfg:** max-num-seqs, max-num-batched-tokens, gpu-memory-utilization, max-model-len, cudagraph_mode/enforce_eager, async_scheduling, prefix-caching. - **Workload:** dataset, ISL/OSL (or mean in/out tokens), concurrency, num-prompts. - **Regime:** warm vs cold. Latency vs throughput tier. - **Stack:** image/vllm commit, bench backend, serving engine. - **Grounding:** `%SoL` (+ ceiling key from `configs/sol-ceilings.yaml` - never inline a peak), sol_rigor (L1-L4), trials n (mean±std), same-node, baseline named. (If the metric is not roofline-bound - e.g. accuracy/acceptance - omit `%SoL` but keep the rest of the descriptor.) - **Per-number exact shape (no smoothing):** when reporting more than one number, keep EACH with its own exact shape (ISL/OSL, concurrency, dataset, regime) - never normalize a set to one uniform descriptor that hides per-point variation (e.g. `c=1 @ ISL1024/OSL256` + `c=64 @ ISL4096/OSL512`, NOT one shared "random"). ## Next lever / BREAKTHROUGH (Grind Mandate) If this skill emits a measured result, its output MUST end by naming the **next perf lever**,
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기