Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a3cc771
[Model] Start Qwen3.8 Flash Next SM70 adaptation
yangzhuxinyzx Aug 26, 2026
a90419b
[Model] Add Qwen3.8 Flash Next SM70 V2 route
yangzhuxinyzx Aug 26, 2026
6b23eea
[Doc] Record verified ModelScope snapshot
yangzhuxinyzx Aug 26, 2026
3fc247d
[Bugfix] Attach Qwen4Exp expert mapping
yangzhuxinyzx Aug 26, 2026
09f68f8
[Core] Report checkpoint name on weight-load failure
yangzhuxinyzx Aug 26, 2026
86b1912
[Bugfix] Preserve QKV shard metadata in auto loading
yangzhuxinyzx Aug 26, 2026
78225e6
[Model] Pass 1Cat GDN output buffer in Qwen4Exp
yangzhuxinyzx Aug 26, 2026
d174f3f
[Model] Honor custom V2 model state providers
yangzhuxinyzx Aug 26, 2026
7fb6068
[Bugfix] Zero heterogeneous hybrid KV pages
yangzhuxinyzx Aug 26, 2026
f73cedb
[Bugfix] Fall back for unsupported custom AR dtypes
yangzhuxinyzx Aug 26, 2026
d64150f
[Core] Invoke custom KV cache bind hooks
yangzhuxinyzx Aug 26, 2026
b37cd74
[Bugfix] Match QSA to local Flash KV layout
yangzhuxinyzx Aug 26, 2026
7349fe2
[Bugfix] Keep PLE scales in model dtype
yangzhuxinyzx Aug 26, 2026
c228412
[Kernel] Decode offloaded PLE FP8 rows on SM70
yangzhuxinyzx Aug 26, 2026
de10e2e
[Bugfix] Preserve dynamic PLE request shapes
yangzhuxinyzx Aug 26, 2026
383ff45
[Kernel][SM70] Bypass single-token NVFP4 MoE sorting
yangzhuxinyzx Aug 27, 2026
da7beb2
[Model][SM70] Enable Qwen4Exp native MTP
yangzhuxinyzx Aug 27, 2026
aa5384d
[Core][SM70] Enable Qwen4Exp prefix caching
yangzhuxinyzx Aug 27, 2026
a21d15e
[Spec Decode][SM70] Handle Qwen4Exp MTP feedback states
yangzhuxinyzx Aug 27, 2026
eb9547e
[Core] Align Qwen4Exp short-conv metadata
yangzhuxinyzx Aug 27, 2026
6097689
[Bugfix] Stage Qwen4Exp spec masks from lists
yangzhuxinyzx Aug 27, 2026
d9a39ea
[Core] Support heterogeneous Mamba state groups
yangzhuxinyzx Aug 27, 2026
b6ded5b
[Doc] Record Qwen4Exp MTP4 bring-up
yangzhuxinyzx Aug 27, 2026
70b63a1
[Spec Decode] Reduce Qwen4Exp MTP cost
yangzhuxinyzx Aug 27, 2026
5abeaa6
[Bench] Record per-prompt speculative acceptance
yangzhuxinyzx Aug 27, 2026
cf5c44a
[Bugfix] Load fused Qwen4Exp MTP experts
yangzhuxinyzx Aug 27, 2026
ceb543c
[Bugfix] Reject incomplete Qwen4Exp MTP loads
yangzhuxinyzx Aug 27, 2026
95fdf66
[Bugfix][SM70] Repair Qwen4Exp integration gates
yangzhuxinyzx Aug 27, 2026
282b693
Merge pull request #359 from 1CatAI/agent/v100-fix-pr345-integration-…
yangzhuxinyzx Aug 27, 2026
0942ef4
Merge remote-tracking branch 'onecat/main' into agent/v100-fix-pr345-…
yangzhuxinyzx Aug 27, 2026
4676f72
Merge pull request #360 from 1CatAI/agent/v100-fix-pr345-main-sync-20…
yangzhuxinyzx Aug 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 79 additions & 1 deletion benchmarks/benchmark_sm70_model_tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,66 @@ def _spec_decoding_summary(
}


def _spec_decoding_delta(
before: list[dict[str, Any]],
after: list[dict[str, Any]],
) -> dict[str, Any] | None:
"""Return speculative-decoding counters added between two snapshots."""

before_summary = _spec_decoding_summary(before)
after_summary = _spec_decoding_summary(after)
if after_summary is None:
return None

before_drafts = int(before_summary["num_drafts"]) if before_summary else 0
before_draft_tokens = (
int(before_summary["num_draft_tokens"]) if before_summary else 0
)
before_accepted = (
int(before_summary["num_accepted_tokens"]) if before_summary else 0
)
after_drafts = int(after_summary["num_drafts"])
after_draft_tokens = int(after_summary["num_draft_tokens"])
after_accepted = int(after_summary["num_accepted_tokens"])

num_drafts = after_drafts - before_drafts
num_draft_tokens = after_draft_tokens - before_draft_tokens
num_accepted_tokens = after_accepted - before_accepted
if num_drafts <= 0:
return None
if num_draft_tokens < 0 or num_accepted_tokens < 0:
raise RuntimeError("Speculative-decoding counters moved backwards")

before_per_pos = (
list(before_summary["accepted_tokens_per_pos"]) if before_summary else []
)
after_per_pos = list(after_summary["accepted_tokens_per_pos"])
width = max(len(before_per_pos), len(after_per_pos))
before_per_pos.extend([0] * (width - len(before_per_pos)))
after_per_pos.extend([0] * (width - len(after_per_pos)))
accepted_tokens_per_pos = [
end - start for start, end in zip(before_per_pos, after_per_pos, strict=True)
]
if any(value < 0 for value in accepted_tokens_per_pos):
raise RuntimeError("Per-position speculative counters moved backwards")

avg_accepted_tokens = num_accepted_tokens / num_drafts
return {
"num_drafts": num_drafts,
"num_draft_tokens": num_draft_tokens,
"num_accepted_tokens": num_accepted_tokens,
"avg_accepted_tokens_no_bonus": avg_accepted_tokens,
"mean_acceptance_length": 1 + avg_accepted_tokens,
"draft_acceptance_rate": (
num_accepted_tokens / num_draft_tokens if num_draft_tokens else None
),
"accepted_tokens_per_pos": accepted_tokens_per_pos,
"per_position_acceptance_rate": [
value / num_drafts for value in accepted_tokens_per_pos
],
}


def _load_prompts(args: argparse.Namespace) -> list[Any]:
if args.input_lens is not None:
if args.input_len is not None or args.prompt or args.prompts_json is not None:
Expand Down Expand Up @@ -1713,6 +1773,7 @@ def _dump(args: argparse.Namespace) -> int:
torch.accelerator.synchronize()
torch.cuda.cudart().cudaProfilerStart()
generate_seconds_by_repeat: list[float] = []
sequential_prompt_metrics: list[dict[str, Any]] = []
outputs = []
try:
for repeat_index in range(args.repeat_count):
Expand All @@ -1724,8 +1785,24 @@ def _dump(args: argparse.Namespace) -> int:
raise RuntimeError("Failed to reset the idle prefix cache")
generate_start = time.perf_counter()
if args.sequential_prompts:
for prompt in prompts:
metrics_before_prompt = _metric_snapshot(llm)
for prompt_index, prompt in enumerate(prompts):
prompt_start = time.perf_counter()
outputs.extend(llm.generate([prompt], sampling_params))
prompt_seconds = time.perf_counter() - prompt_start
metrics_after_prompt = _metric_snapshot(llm)
sequential_prompt_metrics.append(
{
"repeat_index": repeat_index,
"prompt_index": prompt_index,
"generate_seconds": prompt_seconds,
"spec_decoding_metrics": _spec_decoding_delta(
metrics_before_prompt,
metrics_after_prompt,
),
}
)
metrics_before_prompt = metrics_after_prompt
else:
outputs.extend(llm.generate(prompts, sampling_params))
generate_seconds_by_repeat.append(time.perf_counter() - generate_start)
Expand Down Expand Up @@ -1831,6 +1908,7 @@ def _dump(args: argparse.Namespace) -> int:
"eos_token_ids": eos_token_ids,
"metrics_snapshot": metrics_snapshot,
"spec_decoding_metrics": _spec_decoding_summary(metrics_snapshot),
"sequential_prompt_metrics": sequential_prompt_metrics,
"sampling_params": {
"max_tokens": args.max_tokens,
"temperature": args.temperature,
Expand Down
Loading
Loading