Skip to main content

aisimulate-replay-parity

Runs deterministic byte-parity and golden-point qualification campaigns for AI Simulate engine-only offline replay across round-robin vLLM, SGLang, and TRT-LLM configurations, including forced preemption, retraction, handoff, and liveness coverage. Use when validating replay refactors, engine scheduler or event changes, or topology changes against a pinned baseline revision; this skill does not execute performance gates, and the Dynamo KV replay skill covers Router, Planner, KVBM, and other Dynamo-owned composition behavior.

来源信息

仓库
ai-dynamo/aisimulate
最近来源活动
2026年9月9日 04:25
检测到的 SKILL.md 语言
英语
星标
74
分支
34

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
18 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
aisimulate-replay-parity
description
Runs deterministic byte-parity and golden-point qualification campaigns for AI Simulate engine-only offline replay across round-robin vLLM, SGLang, and TRT-LLM configurations, including forced preemption, retraction, handoff, and liveness coverage. Use when validating replay refactors, engine scheduler or event changes, or topology changes against a pinned baseline revision; this skill does not execute performance gates, and the Dynamo KV replay skill covers Router, Planner, KVBM, and other Dynamo-owned composition behavior.
license
Apache-2.0
metadata
{"author":"NVIDIA","tags":["aisimulate","offline-replay","engine","round-robin","parity","regression"]}
# AI Simulate replay parity Compare two revisions of AI Simulate engine-only offline replay using deterministic virtual-time reports. Use the existing replay and test harnesses; extend them only when a required semantic signal is unavailable. This version of the skill does not claim an executable performance gate because current main lacks the required loop-only timing boundary. This campaign requires the built-in `RoundRobinComposition`: synchronous round-robin placement and no scaling. It intentionally excludes injected KV Router, Planner, scaling, KVBM, and other Dynamo-owned composition behavior. It also does not require a same-timestamp event-only progress scenario. Validate that concern with a focused test when a change specifically affects replay liveness or same-time settlement. Before changing or qualifying replay behavior, read `crates/core/src/replay/README.md` and `crates/core/src/replay/CLAUDE.md`. ## Required inputs Resolve and record before running anything: - immutable baseline and candidate commit SHAs; - Rust toolchain, build profile, flags, and host characteristics; - each artifact's exact Cargo features from the relevant manifests; - trace or workload path, upstream repository and commit/blob when external, full-file SHA-256 checksum, and deterministic slice rule and checksum; - engine, topology, concurrency, worker counts, DP/TP sizes, block sizes, and capacities; - the canonical-report exclusion allowlist. Do not compare against moving branches or reuse an artifact after changing its checkout. Do not describe a configuration as "all features"; record explicit feature names. The current `aisimulate-core/replay-bench` feature is empty and is not required for `ReplayDeterminism::CanonicalV1`; do not assign it Dynamo's seeded-router meaning. This skill ships a standalone Rust qualification runner, frozen engine-only configs, and qualified 5,000-row golden points for a pinned main revision. Read [engine-only golden-point seeds](references/engine-only-golden-points.md) before choosing fixtures, running the runner, or claiming long-corpus coverage. ## Stage 1: Pin revisions and artifacts 1. Confirm the baseline is an ancestor or otherwise document the comparison relationship. 2. Create isolated checkouts for both revisions using the same host and Rust toolchain. 3. Apply any temporary determinism correction identically to both revisions. Keep it out of the measured semantic delta and record its patch checksum. 4. Use `scripts/build_runner.py` to copy the exact skill runner source and lockfile into separate build directories and point them at each checkout's `crates/core`. Record the identical runner-source checksum plus each checkout revision and binary checksum. The builder embeds the checkout revision into its binary; never accept a revision supplied by an editable replay config. 5. The runner accepts a frozen `ReplaySpec`, enables `ReplayDeterminism::CanonicalV1`, and emits `CanonicalReplayRecord` plus qualification counters. If it lacks a required correctness or lifecycle signal, add the narrowest reusable support before starting the campaign. Do not reconstruct canonical reports in shell. 6. Build one release artifact per revision with identical explicit features. Reuse that artifact across correctness rows unless a backend genuinely requires a distinct artifact; document any exception. 7. Copy artifacts to a temporary campaign directory. Record exact features, artifact SHA-256, artifact size, and `.text` size when the artifacts are comparable. 8. Return each checkout to its original branch after extracting immutable artifacts. Never build while collecting replay samples. ## Campaign concurrency Treat one engine/topology/frozen-configuration comparison row as the unit of node placement. When scheduler capacity permits, allocate multiple nodes and assign independent rows to them. The nodes do not need to be homogeneous because no individual comparison crosses nodes. Keep the baseline, candidate, all determinism repetitions, and lifecycle evidence for one row on the same node. Use the same prebuilt revision artifacts and inputs throughout the campaign, and record node characteristics and CPU placement for every row. Engine-only replay is normally single-core. Pin each process to one physical core after confirming that assumption during preflight. If thread inspection shows additional runnable workers, pin the process to a fixed CPU set large enough for them and keep the set size, NUMA placement, and affinity identical between baseline and candidate. For correctness, run baseline and candidate repetitions concurrently when the node has sufficient resources. Pin concurrent processes to disjoint CPU sets, give them separate output paths, and ensure they share no mutable state. Keep every repetition in a separate process even when several repetitions run at the same time. Multi-node and within-node correctness parallelism are campaign throughput optimizations; they must not change workload concurrency. ## Stage 2: Establish deterministic reports Require the harness to control every known entropy source: - enable `ReplayDeterminism::CanonicalV1`; - assign stable request UUIDs and preserve authored request correlation; - use stable request ordinals and same-time event sequence numbers; - keep the frozen request, session, and trajectory order; - recursively sort JSON object keys; - sort only explicitly unordered collections such as per-request records; - preserve semantically ordered event and lifecycle arrays; and - use exactly `CANONICAL_RESULT_EXCLUSIONS` from the pinned revision. On current main that closed exclusion list is: - `/summary/wall_time_ms`; - `/summary/processed_tokens_per_s`; - `/summary/processed_output_tokens_per_s`; and - `/planner/html_report_path`. The shared canonical schema retains the planner path for Dynamo compatibility. For the built-in engine-only composition, emit `planner: null` and metadata that identifies round-robin placement, no scaling, backend, topology, worker counts, DP/TP sizes, engine configuration, input checksum, and slice rule. Do not claim that the planner exclusion means a Planner was exercised. This exclusion list is closed: include every other field, and stop for review before adding another exclusion. Make semantic fields deterministic rather than dropping them. Run baseline twice and candidate twice in separate processes. Each revision must produce one unique canonical digest. This is an entropy-leak check, not a statistical trial. If a revision is internally unstable, stop and diagnose it; do not increase repetitions and average the outputs. ## Stage 3: Qualify a long interaction-heavy corpus Prefer a fixed contiguous 5,000-request Mooncake window over many parity repetitions. Preserve arrival order, session structure, and prefix locality. Record the starting offset, request count, trace format, block size, and checksum. Do not randomly sample rows, duplicate a shorter trace, or silently claim a 5,000-request campaign when fewer usable requests exist. The committed two-to-sixteen-row Mooncake fixtures listed in [engine-only golden-point seeds](references/engine-only-golden-points.md) are quick preflight inputs, not the authoritative long-corpus campaign. Qualify and freeze one configuration per comparison row, or per explicitly named configuration family when rows genuinely share every relevant parameter. For each frozen configuration, prove every applicable path was exercised: - round-robin distribution across all configured logical workers; - immediate admission and engine-internal waiting under scheduler pressure; - a small, bounded number of vLLM preemptions or SGLang retractions at the block-capacity edge; - disaggregated prefill/decode handoff; - prefix reuse and terminal cleanup; - attention-DP rank/barrier behavior when selected; and - trace-timestamp, concurrency, multi-turn, or agentic admission semantics selected by the input. Use pressure evidence, per-request records, detailed artifacts, or lifecycle traces rather than inferring paths from successful completion. Target one to three preemptions or retractions per applicable configuration. Zero means the edge was not exercised; repeated preempt/re-admit cycling, rapidly growing pressure counts, an effect-free zero-duration pass, or failure to advance virtual time invalidates the fixture. Tune capacity or concurrency minimally and identically for baseline and candidate within the row or family. Back off rather than accepting a pressure flood. Never tune revisions separately. ### Start from engine-only seeds Read [engine-only golden-point seeds](references/engine-only-golden-points.md) before searching for capacity edges. Use the committed fixed-timing seeds to verify harness wiring, determinism, worker identity, and handoff evidence. They are not substitutes for qualifying internal-polynomial long-corpus configurations on the pinned baseline. Do not import Dynamo's KV-aware capacities or expected counters as AI Simulate golden points. Round-robin placement changes worker assignment, queue pressure, reuse, and preemption/retraction behavior. Matching lifecycle counts do not waive an unstable canonical digest; stop correctness and performance work until internal determinism and cross-revision parity are established. ## Stage 4: Run byte parity Run the frozen long corpus for this authoritative engine-only matrix: | Engine semantics | Topology | Memory path | Placement | Scaling | | --- | --- | --- | --- | --- | | vLLM | Aggregated | Native engine KV | Round-robin | None | | vLLM | Disaggregated, role DP=1 | Native engine KV | Round-robin per pool | None | | vLLM | Disaggregated, prefill DP=2 / decode DP=4 | Native engine KV | Round-robin per pool | None | | SGLang | Aggregated | Native engine KV | Round-robin | None | | SGLang | Disaggregated, role DP=1 | Native engine KV | Round-robin per pool | None | | SGLang | Disaggregated, prefill DP=2 / decode DP=4 | Native engine KV | Round-robin per pool | None | | TRT-LLM guaranteed-no-evict | Aggregated | Native engine KV | Round-robin | None | | TRT-LLM guaranteed-no-evict | Disaggregated, prefill DP=2 / decode DP=4 | Native engine KV | Round-robin per pool | None | Use multiple logical workers in the aggregated and disaggregated rows so round-robin distribution is observable. Add focused aggregated attention-DP rows whenever a change touches grouped ranks, barriers, DP placement, per-rank FPM, or completion visibility. When a pinned baseline predates disaggregated attention-DP or TRT-LLM disaggregated support, record the new row as an intentional semantic exception and qualify it deterministically on the candidate. Do not silently reduce its DP sizes or substitute an aggregated row. For each row: 1. Produce canonical baseline and candidate outputs with the frozen configuration. 2. Compare their bytes or SHA-256 digests exactly. 3. Verify pressure, worker, handoff, reuse, and terminal evidence independently of the digest. 4. Delete matching full reports and retain their digests. 5. Preserve full reports and a focused diff only when outputs disagree. ## Stage 5: Classify semantic differences Byte mismatch is a review gate, not an instruction to preserve incorrect behavior. Allow an intentional mismatch only when the candidate is demonstrably more faithful to the specified engine, scheduler, replay, topology, or handoff semantics. For every proposed exception, record: - the exact fields, requests, or lifecycle events that differ; - the baseline behavior and why it is incorrect or less faithful; - the candidate behavior and the semantic source of truth supporting it; - why the difference is caused by the intended change rather than leaked entropy; - a focused regression test that fails on the old behavior and passes on the correction; - any downstream report or API compatibility impact; and - the reviewer-visible disposition. Use `PASS_WITH_SEMANTIC_EXCEPTIONS` only when every byte difference is covered by such a record. Unexplained, incidental, or merely convenient differences fail. Do not patch the candidate back to known-wrong behavior just to obtain identical bytes. ## Stage 6: Force rare lifecycles when needed Use small deterministic fixtures only for required paths the long corpus cannot reliably trigger: - a single-worker scheduler-pressure fixture; - a vLLM preemption edge targeting one to three preemptions and then completion; - an SGLang retraction edge targeting one to three retractions and then completion; - backend-specific prefill/decode handoff ordering; - attention-DP slowest-rank completion and empty-rank barrier behavior; - exact output-token plans, terminal cleanup, and capped virtual-time behavior; and - balanced liveness at the effect-free zero-duration-pass boundary. Assert bounded pressure, continued virtual-time progress, and the lifecycle itself. A final-completion smoke test does not prove preemption, retraction, handoff, reuse, cleanup, or barrier behavior occurred. Injected scaling-policy fixtures may be focused compatibility tests when a change touches the generic composition boundary, but they are outside the authoritative built-in round-robin/no-scaling matrix. ## Stage 7: Performance follow-up (not implemented by this skill) Stop after semantic qualification when using the current skill. Do not report a performance pass, fail, or inconclusive result from its runner. A future performance extension must first add the loop-only timing boundary and paired orchestration described below; until then, route performance-regression work to a purpose-built harness. The remaining requirements in this stage are the design contract for a future extension, not executable instructions for the current skill. Once that extension exists, it must measure every supported row from Stage 4 with its frozen configuration, reuse the release artifacts from byte parity, and describe the result as engine-only round-robin replay-loop parity. The primary metric is replay execution time. Start its timer after trace normalization, workload construction, and engine/runtime preparation, immediately before the prepared runtime loop; stop it immediately after that loop returns and before collector finalization or report aggregation. Emit this value as `replay_execution_ms`. Record setup and end-to-end time separately as diagnostics. Current main exposes `ReplayReport.throughput.wall_time_ms`, timed broadly from `Replayer::run_inner` entry through report finalization. It is not the authoritative replay-loop metric. If the campaign runner does not expose `replay_execution_ms`, extend the harness before running the gated performance campaign; do not substitute `wall_time_ms` or an outer shell timer. Stage binaries and trace inputs on node-local storage and verify their checksums before warmups. File transfer is campaign setup, not a sample. For each measured invocation, use one iteration, a unique node-local timing output, and a fresh process. Do not emit canonical or full reports during a gated performance invocation; lazy per-request capture, report serialization, and in-process iteration state must not contaminate the metric. For each row: 1. Run five warmups per arm, alternating arms for ten warmups total. 2. Generate and persist a fixed-seed, balanced 60-pair schedule with 30 baseline-first and 30 candidate-first pairs in randomized order. 3. Collect all 60 measured pairs. Keep the two invocations in each pair adjacent and compute `r_i = candidate_replay_execution_ms / baseline_replay_execution_ms` regardless of run order. 4. Treat the ratios as independent and identically distributed, or otherwise exchangeable, only when the campaign can justify that sampling assumption; pair adjacency does not establish it. Predeclare thresholds for serial-dependence diagnostics, including lag autocorrelation and pair-order trends against elapsed time and available temperature or frequency telemetry, and record their results. 5. If diagnostics breach their thresholds or exchangeability cannot be justified, report `INCONCLUSIVE` or use a predeclared dependence-aware method. Do not apply the order-statistic gate. 6. Otherwise sort the 60 ratios. Conditional on the sampling assumption, use the 24th order statistic as the exact distribution-free one-sided 95% lower confidence bound for the population median ratio and the 37th order statistic as the corresponding upper bound. Do not use a Wald interval. 7. Pass when the upper bound is at most `1.05`. 8. Fail when the lower bound is greater than `1.05`. 9. Otherwise report `INCONCLUSIVE`; do not add samples adaptively and claim the original confidence level. Never remove an observation because its value looks like an outlier. Retain every attempted sample and its process status. A replay error, assertion failure, malformed timing record, or other product failure fails or blocks the row; it is not a discardable sample. Only a predeclared environmental condition, such as scheduler eviction, node-health failure, affinity violation, or independently detected competing load, may invalidate a sample. Invalidate both members of that pair, record the evidence and reason, and rerun the complete pair with the same arm order. Never retry or replace a sample silently. A paired bootstrap of log ratios may be reported as a secondary effect-size diagnostic, but it does not decide the gate. Also fail comparable release artifact or `.text` growth above 5% until the added footprint is explained and narrowed. ### Investigate unacceptable overhead When a statistically meaningful regression exceeds the accepted window: 1. Confirm baseline and candidate performed equivalent semantic work. Separate an accepted semantic correction from framework overhead when the correction intentionally adds work. 2. Inspect the diff and hot-path structure for obvious causes: event capture, request cloning, heap allocation, admission vectors, sorting, hashing, dynamic dispatch, lock traffic, or widened generic monomorphization. 3. If static analysis does not identify a convincing cause, profile the representative failing configuration with equivalent release/debug-symbol settings and inputs. 4. Compare self-time, call stacks, allocation-heavy paths, and new monomorphized functions. Attribute the regression to specific code before optimizing or requesting a waiver. 5. Repeat the paired performance gate after any fix. Do not profile concurrently with builds or unrelated load. ## Stage 8: Decide and report Use exactly one semantic result: - `PASS`: all authoritative canonical outputs match; - `PASS_WITH_SEMANTIC_EXCEPTIONS`: every mismatch is an evidenced improvement covered by a regression test; or - `FAIL`: any unexplained mismatch, missing lifecycle evidence, or unstable revision. If a separate supported performance harness was explicitly used, report performance independently as pass, fail, or inconclusive. A semantic exception does not waive an unexplained performance regression. Otherwise state that performance was not measured by this skill. The final report must include: - revision SHAs and determinism-patch checksum, if any; - trace checksum and deterministic slice specification; - every artifact's exact feature manifest and checksum; - each row's frozen configuration, node characteristics, CPU set, and NUMA placement; - one row per engine/topology with canonical digests and lifecycle evidence; - round-robin/no-scaling identity and the exact canonical exclusion allowlist; - every semantic exception record; - comparable artifact and `.text` sizes; - skipped or unsupported coverage without overstating the result. If a separate supported performance harness was used, additionally include its timing scopes, persisted arm-order schedule, all attempted samples and invalidations, paired ratios, sampling assumption, dependence diagnostics, conditional order-statistic confidence bounds, and profiler findings. ## Stage 9: Clean up Delete temporary full reports, traces, binaries, profiler captures, patches, and worktrees after recording the required evidence. Retain full outputs only for unresolved mismatches or performance investigations. Remove task-created Cargo targets when disk pressure matters, but never delete unrelated caches, traces, artifacts, or worktrees.
在 GitHub 查看