feat: trace DeepSeek Chat completion depth

This commit is contained in:
wuyang
2026-07-30 00:24:27 +08:00
parent fb44d15bb8
commit 8bb488f275
23 changed files with 1507052 additions and 33 deletions
+86
View File
@@ -586,3 +586,89 @@ See `research/DEEPSEEK_V2_LITE_CHAT_BEHAVIOR_PROTOCOL.md` and
`research/DEEPSEEK_V2_LITE_CHAT_BEHAVIOR_AUDIT.md` for the preregistered
contract, output-divergence table, offload device map, truncation boundary,
rerun coverage, execution fixes, primary sources, and forbidden conclusions.
## Completion-aware 512-token evaluation
The completion run uses the same 16 sources and eight-condition batches but
reruns all 128 cells with one uniform 512-token budget. The successful formal
placement leaves embeddings and layers 0–23 on CUDA and offloads layers 24–26,
final norm, and LM head. `expandable_segments:True` is part of the recorded
runtime contract.
```bash
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True \
PYTHONPATH=/path/to/transformers-4.41.2-deps \
python -B experiments/deepseek/v2_lite_chat_special_token_behavior_probe.py \
--artifact-dir /path/to/deepseek-v2-lite-chat \
--reference-routing-json \
src/data/deepseek-v2-lite-routing-special-token-family-control.json \
--human-eval /path/to/HumanEval.jsonl.gz \
--gsm8k /path/to/gsm8k/test.jsonl \
--tnews /path/to/tnews/test.json \
--tnews-archive /path/to/tnews_public.zip \
--wikitext /path/to/wikitext-validation.parquet \
--output src/data/deepseek-v2-lite-chat-completion-512.json \
--per-domain 4 \
--max-new-tokens 512 \
--gpu-memory 28GiB \
--cpu-memory 80GiB
```
The evaluator separates stopping, semantic terminal state, evaluator coverage,
and correctness. Each HumanEval candidate runs in a fresh pinned, networkless,
read-only Docker container with no host mounts:
```bash
python -B experiments/deepseek/v2_lite_chat_completion_evaluator.py \
--behavior-json \
src/data/deepseek-v2-lite-chat-completion-512.json \
--baseline-json src/data/deepseek-v2-lite-chat-behavior.json \
--human-eval /path/to/HumanEval.jsonl.gz \
--gsm8k /path/to/gsm8k/test.jsonl \
--sandbox-image \
python:3.11-alpine@sha256:25976e9d34a0fab1f278cae931f34c8303d97bf0c0d7f85b6b4dcf641d7702a4 \
--output \
src/data/deepseek-v2-lite-chat-completion-512-eval.json
```
The formal run reaches natural EOS in 121/128 cells, up from 31/128 at the
128-token budget. Strict-complete GSM8K numeric exact is 23/32; HumanEval
official-test pass is 24/32. These are four source tasks per domain, not
benchmark estimates. A fresh-process one-source-per-domain rerun reproduces
all 32 complete generated token sequences.
## Full 27-layer Chat hidden-state and router trace
`v2_lite_chat_full_depth_trace.py` performs a prompt-only `use_cache=False`
forward on the same checkpoint and inputs. It captures hashes and statistics
for embedding, every decoder-layer output, final norm, and every MoE gate.
Boundary-crossing tokenizer tokens are excluded from the exact target-content
scope.
```bash
PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True \
PYTHONPATH=/path/to/transformers-4.41.2-deps \
python -B experiments/deepseek/v2_lite_chat_full_depth_trace.py \
--artifact-dir /path/to/deepseek-v2-lite-chat \
--reference-routing-json \
src/data/deepseek-v2-lite-routing-special-token-family-control.json \
--human-eval /path/to/HumanEval.jsonl.gz \
--gsm8k /path/to/gsm8k/test.jsonl \
--tnews /path/to/tnews/test.json \
--tnews-archive /path/to/tnews_public.zip \
--wikitext /path/to/wikitext-validation.parquet \
--output src/data/deepseek-v2-lite-chat-full-depth.json \
--per-domain 4 \
--gpu-memory 28GiB \
--cpu-memory 80GiB
```
The formal trace covers 1,537 exact interior content tokens per condition,
29 hidden stages, 26 gates, and 1,918,176 top-6 route decisions. A fresh
four-source rerun reproduces 1,856 hidden tensor hashes, 1,664 ordered route
hashes, 1,664 route-weight hashes, and every derived comparison.
See `research/DEEPSEEK_V2_LITE_CHAT_COMPLETION_PROTOCOL.md` and
`research/DEEPSEEK_V2_LITE_CHAT_COMPLETION_DEPTH_AUDIT.md` for the OOM
amendment, task evaluators, completion table, depth curves, reproduction
audit, artifact hashes, and claim boundaries.
@@ -0,0 +1,701 @@
#!/usr/bin/env python3
"""Evaluate completion state, GSM8K answers, and HumanEval code safely.
The input is a raw JSON emitted by
v2_lite_chat_special_token_behavior_probe.py. Generated code is executed only
inside one fresh, networkless, read-only Docker container per candidate. The
result preserves fixed-budget and strict-completion metrics separately.
"""
from __future__ import annotations
import argparse
import ast
import gzip
import hashlib
import json
import re
import subprocess
import time
from collections import Counter
from decimal import Decimal, InvalidOperation
from pathlib import Path
from statistics import mean
from typing import Any
NUMBER = r"[-+]?(?:\d[\d,]*\.?\d*|\.\d+)"
NUMBER_PATTERN = re.compile(NUMBER)
BOXED_PATTERN = re.compile(
rf"\\boxed\s*\{{\s*({NUMBER})\s*\}}",
flags=re.IGNORECASE,
)
HASH_PATTERN = re.compile(
rf"####\s*({NUMBER})",
flags=re.IGNORECASE,
)
ANSWER_PATTERN = re.compile(
rf"(?:final\s+answer|answer|result|total|profit)"
rf"(?:\s+(?:is|equals|will\s+be))?\s*[:=]?\s*"
rf"(?:\$|USD\s*)?({NUMBER})",
flags=re.IGNORECASE,
)
FENCE_PATTERN = re.compile(
r"```(?P<lang>[A-Za-z0-9_+-]*)[ \t]*\n?"
r"(?P<body>.*?)(?:```|$)",
flags=re.DOTALL,
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument("--behavior-json", type=Path, required=True)
parser.add_argument("--baseline-json", type=Path)
parser.add_argument("--human-eval", type=Path, required=True)
parser.add_argument("--gsm8k", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument(
"--sandbox-image",
required=True,
help="Pinned image reference including @sha256 digest.",
)
parser.add_argument("--timeout-seconds", type=float, default=5.0)
parser.add_argument("--skip-code-execution", action="store_true")
return parser.parse_args()
def sha256_bytes(payload: bytes) -> str:
return hashlib.sha256(payload).hexdigest()
def sha256_file(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as handle:
while chunk := handle.read(16 * 1024 * 1024):
digest.update(chunk)
return digest.hexdigest()
def canonical_hash(value: Any) -> str:
return sha256_bytes(
json.dumps(
value,
ensure_ascii=False,
sort_keys=True,
separators=(",", ":"),
).encode()
)
def load_jsonl(path: Path) -> list[dict[str, Any]]:
with path.open(encoding="utf-8") as handle:
return [json.loads(line) for line in handle if line.strip()]
def load_tasks(
human_eval_path: Path,
gsm8k_path: Path,
) -> tuple[dict[str, dict[str, Any]], dict[str, dict[str, Any]]]:
with gzip.open(human_eval_path, "rt", encoding="utf-8") as handle:
human_eval = {
row["task_id"]: row
for line in handle
if line.strip()
for row in [json.loads(line)]
}
gsm8k = {
f"gsm8k/test/{index:04d}": row
for index, row in enumerate(load_jsonl(gsm8k_path))
}
return human_eval, gsm8k
def normalize_number(value: str | None) -> str | None:
if value is None:
return None
cleaned = value.replace(",", "").strip().rstrip(".")
try:
number = Decimal(cleaned)
except InvalidOperation:
return None
normalized = format(number.normalize(), "f")
if "." in normalized:
normalized = normalized.rstrip("0").rstrip(".")
return "0" if normalized in {"-0", "+0"} else normalized
def last_match(
pattern: re.Pattern[str],
text: str,
) -> str | None:
matches = list(pattern.finditer(text))
return matches[-1].group(1) if matches else None
def evaluate_math(
text: str,
hit_eos: bool,
gold_answer: str,
) -> dict[str, Any]:
candidates = [
("boxed", last_match(BOXED_PATTERN, text)),
("hash_marker", last_match(HASH_PATTERN, text)),
("answer_phrase", last_match(ANSWER_PATTERN, text)),
]
method = "none"
extracted = None
for name, value in candidates:
if value is not None:
method = name
extracted = value
break
explicit_terminal = extracted is not None
if extracted is None:
values = NUMBER_PATTERN.findall(text)
if values:
method = "last_number_fallback"
extracted = values[-1]
gold_values = NUMBER_PATTERN.findall(
gold_answer.rsplit("####", 1)[-1]
)
gold = normalize_number(gold_values[-1] if gold_values else None)
predicted = normalize_number(extracted)
fixed_budget_exact = (
gold is not None
and predicted is not None
and gold == predicted
)
semantic_terminal = bool(hit_eos or explicit_terminal)
return {
"gold_final": gold,
"predicted_final": predicted,
"extraction_method": method,
"explicit_final_marker": explicit_terminal,
"semantic_terminal": semantic_terminal,
"evaluator_covered": predicted is not None,
"fixed_budget_numeric_exact": fixed_budget_exact,
"strict_complete_numeric_exact": (
fixed_budget_exact and semantic_terminal
),
}
def code_fences(text: str) -> list[dict[str, str | bool]]:
rows = []
for match in FENCE_PATTERN.finditer(text):
language = match.group("lang").lower()
body = match.group("body").strip()
rows.append(
{
"language": language,
"body": body,
"closed": text[match.start():match.end()].rstrip().endswith(
"```"
),
}
)
return rows
def extract_code(
text: str,
prompt: str,
entry_point: str,
) -> dict[str, Any]:
target = re.compile(
rf"(?m)^\s*(?:async\s+)?def\s+{re.escape(entry_point)}\s*\("
)
fences = code_fences(text)
chosen = next(
(
row for row in fences
if target.search(str(row["body"]))
and row["language"] in {"", "py", "python", "python3"}
),
None,
)
if chosen is None:
chosen = next(
(
row for row in fences
if row["language"] in {"", "py", "python", "python3"}
),
None,
)
if chosen is not None:
raw = str(chosen["body"])
mode = "fenced"
fence_closed = bool(chosen["closed"])
else:
match = target.search(text)
if match:
raw = text[match.start():].strip()
mode = "direct_definition"
else:
raw = text.strip()
mode = "prompt_completion"
fence_closed = False
contains_entry_point = target.search(raw) is not None
candidate = raw if contains_entry_point else prompt + raw
try:
ast.parse(candidate)
ast_ok = True
ast_error = None
except SyntaxError as error:
ast_ok = False
ast_error = {
"line": error.lineno,
"offset": error.offset,
"type": type(error).__name__,
}
return {
"candidate": candidate,
"candidate_sha256": sha256_bytes(candidate.encode()),
"extraction_mode": mode,
"contains_entry_point_definition": contains_entry_point,
"closed_code_fence": fence_closed,
"python_ast_parse": ast_ok,
"parse_error": ast_error,
}
def sandbox_harness(
candidate: str,
test: str,
entry_point: str,
) -> str:
return (
"import sys\n"
"try:\n"
+ "\n".join(
f" {line}" if line else ""
for line in candidate.splitlines()
)
+ "\n"
+ "\n".join(
f" {line}" if line else ""
for line in test.splitlines()
)
+ f"\n check({entry_point})\n"
+ "except AssertionError:\n"
+ " raise SystemExit(10)\n"
+ "except BaseException:\n"
+ " raise SystemExit(11)\n"
+ "raise SystemExit(0)\n"
)
def execute_code(
candidate: str,
task: dict[str, Any],
image: str,
timeout_seconds: float,
) -> dict[str, Any]:
harness = sandbox_harness(
candidate,
task["test"],
task["entry_point"],
)
command = [
"docker",
"run",
"--rm",
"-i",
"--network",
"none",
"--read-only",
"--tmpfs",
"/tmp:rw,noexec,nosuid,size=16m",
"--memory",
"256m",
"--memory-swap",
"256m",
"--pids-limit",
"64",
"--cpus",
"0.5",
"--cap-drop",
"ALL",
"--security-opt",
"no-new-privileges",
"--user",
"65534:65534",
image,
"python",
"-I",
"-",
]
started = time.perf_counter()
try:
completed = subprocess.run(
command,
input=harness.encode(),
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
timeout=timeout_seconds,
check=False,
)
except subprocess.TimeoutExpired:
return {
"status": "timeout",
"return_code": None,
"runtime_ms": (time.perf_counter() - started) * 1000,
"harness_sha256": sha256_bytes(harness.encode()),
}
runtime_ms = (time.perf_counter() - started) * 1000
statuses = {
0: "passed",
10: "assertion_failed",
11: "runtime_error",
}
return {
"status": statuses.get(
completed.returncode,
"sandbox_error",
),
"return_code": completed.returncode,
"runtime_ms": runtime_ms,
"harness_sha256": sha256_bytes(harness.encode()),
}
def evaluate_code(
text: str,
hit_eos: bool,
task: dict[str, Any],
image: str,
timeout_seconds: float,
skip_execution: bool,
) -> dict[str, Any]:
extracted = extract_code(
text,
task["prompt"],
task["entry_point"],
)
execution = {
"status": "not_run",
"return_code": None,
"runtime_ms": None,
"harness_sha256": None,
}
if extracted["python_ast_parse"] and not skip_execution:
execution = execute_code(
extracted["candidate"],
task,
image,
timeout_seconds,
)
passed = execution["status"] == "passed"
semantic_terminal = bool(
hit_eos
or extracted["closed_code_fence"]
or passed
)
return {
key: value
for key, value in extracted.items()
if key != "candidate"
} | {
"semantic_terminal": semantic_terminal,
"evaluator_covered": (
extracted["python_ast_parse"]
and execution["status"] != "not_run"
),
"execution": execution,
"fixed_budget_tests_pass": passed,
"strict_complete_tests_pass": passed and semantic_terminal,
}
def completion_class(
output: dict[str, Any],
task_evaluation: dict[str, Any] | None,
) -> str:
if output["hit_eos"]:
return "NATURAL_EOS"
if (
task_evaluation is not None
and task_evaluation.get("semantic_terminal")
):
return "TASK_TERMINAL_BEFORE_EOS"
if output["stopped_at_max_new_tokens"]:
if (
task_evaluation is not None
and task_evaluation.get("extraction_method")
== "last_number_fallback"
):
return "BUDGET_TRUNCATED_WITH_FALLBACK_ONLY"
return "BUDGET_TRUNCATED_UNRESOLVED"
return "OTHER_STOP"
def baseline_index(
baseline: dict[str, Any] | None,
) -> dict[tuple[str, str], dict[str, Any]]:
if baseline is None:
return {}
return {
(source["id"], output["condition"]): output
for source in baseline["sources"]
for output in source["outputs"]
}
def prefix_audit(
source_id: str,
output: dict[str, Any],
baseline_rows: dict[tuple[str, str], dict[str, Any]],
) -> dict[str, Any] | None:
prior = baseline_rows.get((source_id, output["condition"]))
if prior is None:
return None
reference = prior["generated_token_ids"]
observed = output["generated_token_ids"][: len(reference)]
return {
"baseline_generated_tokens": len(reference),
"compared_tokens": min(
len(reference),
len(output["generated_token_ids"]),
),
"prompt_hash_exact": (
prior["prompt_token_ids_sha256"]
== output["prompt_token_ids_sha256"]
),
"generated_prefix_exact": observed == reference,
"baseline_hit_eos": prior["hit_eos"],
}
def summarize(rows: list[dict[str, Any]]) -> dict[str, Any]:
by_condition: dict[str, dict[str, Any]] = {}
conditions = sorted({row["condition"] for row in rows})
for condition in conditions:
subset = [
row for row in rows
if row["condition"] == condition
]
math_rows = [
row for row in subset
if row["domain"] == "math"
]
code_rows = [
row for row in subset
if row["domain"] == "code"
]
by_condition[condition] = {
"outputs": len(subset),
"natural_eos": sum(row["hit_eos"] for row in subset),
"budget_truncated": sum(
row["stopped_at_max_new_tokens"]
for row in subset
),
"mean_generated_tokens": mean(
row["generated_tokens"] for row in subset
),
"completion_classes": dict(
Counter(row["completion_class"] for row in subset)
),
"math_fixed_budget_exact": sum(
row["task_evaluation"][
"fixed_budget_numeric_exact"
]
for row in math_rows
),
"math_strict_complete_exact": sum(
row["task_evaluation"][
"strict_complete_numeric_exact"
]
for row in math_rows
),
"math_sources": len(math_rows),
"code_ast_parse": sum(
row["task_evaluation"]["python_ast_parse"]
for row in code_rows
),
"code_executed": sum(
row["task_evaluation"]["execution"]["status"]
!= "not_run"
for row in code_rows
),
"code_tests_pass": sum(
row["task_evaluation"]["fixed_budget_tests_pass"]
for row in code_rows
),
"code_sources": len(code_rows),
}
prefix_rows = [
row["baseline_prefix_audit"]
for row in rows
if row["baseline_prefix_audit"] is not None
]
return {
"outputs": len(rows),
"natural_eos": sum(row["hit_eos"] for row in rows),
"budget_truncated": sum(
row["stopped_at_max_new_tokens"] for row in rows
),
"completion_classes": dict(
Counter(row["completion_class"] for row in rows)
),
"baseline_prefix": {
"cells": len(prefix_rows),
"prompt_hash_exact": sum(
row["prompt_hash_exact"] for row in prefix_rows
),
"generated_prefix_exact": sum(
row["generated_prefix_exact"] for row in prefix_rows
),
},
"by_condition": by_condition,
}
def main() -> None:
args = parse_args()
for path in (
args.behavior_json,
args.human_eval,
args.gsm8k,
):
if not path.is_file():
raise FileNotFoundError(path)
if args.baseline_json is not None and not args.baseline_json.is_file():
raise FileNotFoundError(args.baseline_json)
if "@sha256:" not in args.sandbox_image:
raise ValueError("--sandbox-image must include an immutable digest")
if args.timeout_seconds <= 0:
raise ValueError("--timeout-seconds must be positive")
behavior = json.loads(
args.behavior_json.read_text(encoding="utf-8")
)
baseline = (
json.loads(args.baseline_json.read_text(encoding="utf-8"))
if args.baseline_json is not None
else None
)
baseline_rows = baseline_index(baseline)
human_eval, gsm8k = load_tasks(args.human_eval, args.gsm8k)
rows = []
for source in behavior["sources"]:
for output in source["outputs"]:
evaluation = None
if source["domain"] == "math":
evaluation = evaluate_math(
output["text"],
output["hit_eos"],
gsm8k[source["id"]]["answer"],
)
elif source["domain"] == "code":
evaluation = evaluate_code(
output["text"],
output["hit_eos"],
human_eval[source["id"]],
args.sandbox_image,
args.timeout_seconds,
args.skip_code_execution,
)
rows.append(
{
"source_id": source["id"],
"domain": source["domain"],
"condition": output["condition"],
"generated_tokens": output["generated_tokens"],
"hit_eos": output["hit_eos"],
"stopped_at_max_new_tokens": (
output["stopped_at_max_new_tokens"]
),
"prompt_token_ids_sha256": (
output["prompt_token_ids_sha256"]
),
"generated_token_ids_sha256": (
output["generated_token_ids_sha256"]
),
"text_sha256": output["text_sha256"],
"task_evaluation": evaluation,
"completion_class": completion_class(
output,
evaluation,
),
"baseline_prefix_audit": prefix_audit(
source["id"],
output,
baseline_rows,
),
}
)
result = {
"schema_version": 1,
"input": {
"behavior_path": str(args.behavior_json),
"behavior_sha256": sha256_file(args.behavior_json),
"baseline_path": (
str(args.baseline_json)
if args.baseline_json is not None
else None
),
"baseline_sha256": (
sha256_file(args.baseline_json)
if args.baseline_json is not None
else None
),
"human_eval_sha256": sha256_file(args.human_eval),
"gsm8k_sha256": sha256_file(args.gsm8k),
"model_revision": behavior["model"]["revision"],
"max_new_tokens": behavior[
"generation_contract"
]["max_new_tokens"],
},
"sandbox": {
"image": args.sandbox_image,
"timeout_seconds": args.timeout_seconds,
"code_execution_skipped": args.skip_code_execution,
"network": "none",
"filesystem": "read-only",
"user": "65534:65534",
"capabilities": "ALL dropped",
"memory": "256m",
"memory_swap": "256m",
"pids_limit": 64,
"cpus": 0.5,
"tmpfs": "/tmp:rw,noexec,nosuid,size=16m",
"host_mounts": 0,
},
"rows": rows,
"summary": summarize(rows),
"claim_boundary": [
"Four math and four code sources are not benchmark estimates.",
"Completion-conditioned metrics are selection-biased diagnostics.",
"A passing HumanEval test is functional evidence, not code-safety evidence.",
"Fallback last-number extraction is not strict completion.",
"Counterfactual token sequences are not official-valid chats.",
],
"content_hash": canonical_hash(rows),
}
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(
json.dumps(result, ensure_ascii=False, indent=2) + "\n",
encoding="utf-8",
)
payload = args.output.read_bytes()
print(
json.dumps(
{
"output": str(args.output),
"sha256": sha256_bytes(payload),
"bytes": len(payload),
"summary": result["summary"],
},
ensure_ascii=False,
indent=2,
)
)
if __name__ == "__main__":
main()
@@ -0,0 +1,872 @@
#!/usr/bin/env python3
"""Trace all 27 Chat decoder layers and all 26 MoE gates.
The probe reuses the fixed 16-source, eight-condition completion cohort but
runs prompt-only full-depth forwards. It stores hashes and summaries rather
than raw hidden tensors. Target-content comparisons use only byte-identical
interior content tokens; boundary-crossing tokens are explicitly excluded.
"""
from __future__ import annotations
import argparse
import hashlib
import json
import math
import os
import platform
import resource
import time
from datetime import datetime, timezone
from pathlib import Path
from statistics import mean
from typing import Any
import accelerate
import safetensors
import torch
import torch.nn.functional as F
import transformers
from transformers import AutoTokenizer
import v2_lite_chat_special_token_behavior_probe as behavior
import v2_lite_routing_special_token_family_control as special
EDGE_PAIRS = {
"system_eos": ("s0_eos", "s1_eos"),
"system_bos": ("s0_bos", "s1_bos"),
"system_x": ("s0_x", "s1_x"),
"system_period": ("s0_period", "s1_period"),
"bos_at_s0": ("s0_eos", "s0_bos"),
"bos_at_s1": ("s1_eos", "s1_bos"),
"x_at_s0": ("s0_eos", "s0_x"),
"x_at_s1": ("s1_eos", "s1_x"),
"period_at_s0": ("s0_eos", "s0_period"),
"period_at_s1": ("s1_eos", "s1_period"),
}
SCOPES = ("target_content", "full_input")
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser()
parser.add_argument("--artifact-dir", type=Path, required=True)
parser.add_argument("--reference-routing-json", type=Path, required=True)
parser.add_argument("--human-eval", type=Path, required=True)
parser.add_argument("--gsm8k", type=Path, required=True)
parser.add_argument("--tnews", type=Path, required=True)
parser.add_argument("--tnews-archive", type=Path, required=True)
parser.add_argument("--wikitext", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument(
"--domains",
nargs="+",
choices=behavior.DEFAULT_DOMAINS,
default=list(behavior.DEFAULT_DOMAINS),
)
parser.add_argument("--per-domain", type=int, default=1)
parser.add_argument("--gpu-memory", default="28GiB")
parser.add_argument("--cpu-memory", default="80GiB")
parser.add_argument("--captured-at", default=None)
return parser.parse_args()
def canonical_hash(value: Any) -> str:
payload = json.dumps(
value,
ensure_ascii=False,
sort_keys=True,
separators=(",", ":"),
).encode()
return hashlib.sha256(payload).hexdigest()
def tensor_hash(tensor: torch.Tensor) -> str:
value = tensor.detach().cpu().contiguous()
header = json.dumps(
{
"shape": list(value.shape),
"dtype": str(value.dtype),
},
separators=(",", ":"),
).encode()
raw = value.view(torch.uint8).numpy().tobytes()
return hashlib.sha256(header + b"\0" + raw).hexdigest()
def validate_args(args: argparse.Namespace) -> None:
if args.per_domain <= 0:
raise ValueError("--per-domain must be positive")
for path in (
args.artifact_dir,
args.reference_routing_json,
args.human_eval,
args.gsm8k,
args.tnews,
args.tnews_archive,
args.wikitext,
):
if not path.exists():
raise FileNotFoundError(path)
missing = [
name
for name in behavior.MODEL_FILES
if not (args.artifact_dir / name).is_file()
]
if missing:
raise FileNotFoundError(
f"artifact directory is incomplete: {missing}"
)
def condition_positions(
variants: dict[str, dict[str, Any]],
batch_tokens: int,
) -> dict[str, dict[str, list[int]]]:
result = {}
for condition in special.CONDITIONS:
variant = variants[condition]
padding = batch_tokens - variant["tokens"]
result[condition] = {
"target_content": [
padding + int(position)
for position in variant["content_positions"]
],
"full_input": list(range(padding, batch_tokens)),
}
return result
def hidden_stats(value: torch.Tensor) -> dict[str, Any]:
fp32 = value.float()
return {
"shape": list(value.shape),
"dtype": str(value.dtype),
"tensor_sha256": tensor_hash(value),
"mean": fp32.mean().item(),
"std": fp32.std(unbiased=False).item(),
"rms": fp32.square().mean().sqrt().item(),
"max_abs": fp32.abs().max().item(),
}
def compare_hidden(
left: torch.Tensor,
right: torch.Tensor,
) -> dict[str, Any]:
if left.shape != right.shape:
raise RuntimeError(
f"hidden comparison shape mismatch: {left.shape} != "
f"{right.shape}"
)
left_fp32 = left.float()
right_fp32 = right.float()
delta = right_fp32 - left_fp32
denominator = left_fp32.norm(dim=-1).clamp_min(1e-12)
relative = delta.norm(dim=-1) / denominator
cosine = F.cosine_similarity(
left_fp32,
right_fp32,
dim=-1,
eps=1e-12,
).clamp(-1.0, 1.0)
exact = (left == right).all(dim=-1)
return {
"tokens": left.shape[0],
"exact_hidden_rows": exact.sum().item(),
"mean_cosine_similarity": cosine.mean().item(),
"min_cosine_similarity": cosine.min().item(),
"mean_relative_l2": relative.mean().item(),
"max_abs_delta": delta.abs().max().item(),
}
def route_distribution(
route_ids: torch.Tensor,
route_weights: torch.Tensor,
experts: int,
) -> dict[str, Any]:
loads = torch.bincount(
route_ids.reshape(-1),
minlength=experts,
).to(torch.int64)
weighted = torch.zeros(experts, dtype=torch.float64)
weighted.scatter_add_(
0,
route_ids.reshape(-1),
route_weights.reshape(-1).to(torch.float64),
)
total = loads.sum().item()
probabilities = loads.to(torch.float64) / max(total, 1)
nonzero = probabilities[probabilities > 0]
entropy = (
-(nonzero * nonzero.log()).sum().item() / math.log(experts)
if len(nonzero)
else 0.0
)
mean_load = loads.double().mean()
cv = (
loads.double().std(unbiased=False) / mean_load
if mean_load > 0
else torch.tensor(0.0)
)
return {
"tokens": route_ids.shape[0],
"top_k": route_ids.shape[1],
"decisions": total,
"ordered_route_sha256": canonical_hash(route_ids.tolist()),
"route_weight_sha256": tensor_hash(route_weights),
"loads": loads.tolist(),
"weighted_loads": weighted.tolist(),
"unique_experts": int((loads > 0).sum().item()),
"load_cv": cv.item(),
"normalized_load_entropy": entropy,
"max_load_share": probabilities.max().item(),
}
def normalized_load(loads: torch.Tensor) -> torch.Tensor:
value = loads.to(torch.float64)
return value / value.sum().clamp_min(1e-12)
def compare_routes(
left_ids: torch.Tensor,
left_weights: torch.Tensor,
right_ids: torch.Tensor,
right_weights: torch.Tensor,
experts: int,
) -> dict[str, Any]:
if left_ids.shape != right_ids.shape:
raise RuntimeError(
f"route comparison shape mismatch: {left_ids.shape} != "
f"{right_ids.shape}"
)
ordered_exact = (left_ids == right_ids).all(dim=-1)
left_sorted = left_ids.sort(dim=-1).values
right_sorted = right_ids.sort(dim=-1).values
set_exact = (left_sorted == right_sorted).all(dim=-1)
left_hot = F.one_hot(
left_ids,
num_classes=experts,
).sum(dim=1).bool()
right_hot = F.one_hot(
right_ids,
num_classes=experts,
).sum(dim=1).bool()
intersection = (left_hot & right_hot).sum(dim=-1)
union = (left_hot | right_hot).sum(dim=-1).clamp_min(1)
left_token_weighted = torch.zeros(
left_ids.shape[0],
experts,
dtype=torch.float64,
)
right_token_weighted = torch.zeros_like(left_token_weighted)
left_token_weighted.scatter_add_(
1,
left_ids,
left_weights.to(torch.float64),
)
right_token_weighted.scatter_add_(
1,
right_ids,
right_weights.to(torch.float64),
)
token_weighted_tv = 0.5 * (
left_token_weighted - right_token_weighted
).abs().sum(dim=-1)
left_load = torch.bincount(
left_ids.reshape(-1),
minlength=experts,
)
right_load = torch.bincount(
right_ids.reshape(-1),
minlength=experts,
)
load_tv = 0.5 * (
normalized_load(left_load)
- normalized_load(right_load)
).abs().sum()
return {
"tokens": left_ids.shape[0],
"ordered_topk_exact_tokens": ordered_exact.sum().item(),
"set_exact_tokens": set_exact.sum().item(),
"mean_set_jaccard": (
intersection.to(torch.float64)
/ union.to(torch.float64)
).mean().item(),
"mean_token_weighted_tv": token_weighted_tv.mean().item(),
"aggregate_load_tv": load_tv.item(),
}
class TraceCapture:
def __init__(self, experts: int) -> None:
self.experts = experts
self.positions: dict[str, dict[str, list[int]]] = {}
self.batch_tokens = 0
self.hidden: dict[str, Any] = {}
self.routes: dict[str, Any] = {}
def start(
self,
positions: dict[str, dict[str, list[int]]],
batch_tokens: int,
) -> None:
self.positions = positions
self.batch_tokens = batch_tokens
self.hidden = {}
self.routes = {}
def hidden_hook(self, stage: str):
def hook(
_module: torch.nn.Module,
_inputs: tuple[Any, ...],
output: Any,
) -> None:
tensor = output[0] if isinstance(output, tuple) else output
if tensor.ndim != 3:
raise RuntimeError(
f"{stage} hidden rank {tensor.ndim}, expected 3"
)
cpu = tensor.detach().cpu()
condition_values: dict[str, dict[str, torch.Tensor]] = {}
condition_rows = {}
for row, condition in enumerate(special.CONDITIONS):
condition_values[condition] = {}
condition_rows[condition] = {}
for scope in SCOPES:
positions = self.positions[condition][scope]
value = cpu[row, positions, :].contiguous()
condition_values[condition][scope] = value
condition_rows[condition][scope] = hidden_stats(value)
comparisons = {}
for name, (left, right) in EDGE_PAIRS.items():
comparisons[name] = compare_hidden(
condition_values[left]["target_content"],
condition_values[right]["target_content"],
)
self.hidden[stage] = {
"conditions": condition_rows,
"target_comparisons": comparisons,
}
return hook
def gate_hook(self, layer: int):
def hook(
_module: torch.nn.Module,
_inputs: tuple[Any, ...],
output: Any,
) -> None:
route_ids, route_weights, _aux = output
top_k = route_ids.shape[-1]
ids = route_ids.detach().reshape(
len(special.CONDITIONS),
self.batch_tokens,
top_k,
).cpu()
weights = route_weights.detach().reshape(
len(special.CONDITIONS),
self.batch_tokens,
top_k,
).cpu()
values: dict[
str,
dict[str, tuple[torch.Tensor, torch.Tensor]],
] = {}
condition_rows = {}
for row, condition in enumerate(special.CONDITIONS):
values[condition] = {}
condition_rows[condition] = {}
for scope in SCOPES:
positions = self.positions[condition][scope]
scoped_ids = ids[row, positions, :].contiguous()
scoped_weights = weights[
row,
positions,
:,
].contiguous()
values[condition][scope] = (
scoped_ids,
scoped_weights,
)
condition_rows[condition][scope] = (
route_distribution(
scoped_ids,
scoped_weights,
self.experts,
)
)
comparisons = {}
for name, (left, right) in EDGE_PAIRS.items():
left_ids, left_weights = values[left][
"target_content"
]
right_ids, right_weights = values[right][
"target_content"
]
comparisons[name] = compare_routes(
left_ids,
left_weights,
right_ids,
right_weights,
self.experts,
)
self.routes[f"layer_{layer:02d}"] = {
"layer": layer,
"conditions": condition_rows,
"target_comparisons": comparisons,
}
return hook
def aggregate_trace(sources: list[dict[str, Any]]) -> dict[str, Any]:
hidden_stages = [
"embedding",
*(f"layer_{index:02d}" for index in range(27)),
"final_norm",
]
router_layers = [
f"layer_{index:02d}"
for index in range(1, 27)
]
hidden = {}
for stage in hidden_stages:
hidden[stage] = {}
for edge in EDGE_PAIRS:
rows = [
source["hidden_stages"][stage][
"target_comparisons"
][edge]
for source in sources
]
tokens = sum(row["tokens"] for row in rows)
hidden[stage][edge] = {
"sources": len(rows),
"tokens": tokens,
"exact_hidden_rows": sum(
row["exact_hidden_rows"] for row in rows
),
"token_weighted_mean_cosine_similarity": sum(
row["mean_cosine_similarity"] * row["tokens"]
for row in rows
) / tokens,
"source_mean_relative_l2": mean(
row["mean_relative_l2"] for row in rows
),
"max_abs_delta": max(
row["max_abs_delta"] for row in rows
),
}
routes = {}
for layer in router_layers:
routes[layer] = {}
for edge in EDGE_PAIRS:
rows = [
source["router_layers"][layer][
"target_comparisons"
][edge]
for source in sources
]
tokens = sum(row["tokens"] for row in rows)
routes[layer][edge] = {
"sources": len(rows),
"tokens": tokens,
"ordered_topk_exact_tokens": sum(
row["ordered_topk_exact_tokens"] for row in rows
),
"set_exact_tokens": sum(
row["set_exact_tokens"] for row in rows
),
"token_weighted_mean_set_jaccard": sum(
row["mean_set_jaccard"] * row["tokens"]
for row in rows
) / tokens,
"source_mean_token_weighted_tv": mean(
row["mean_token_weighted_tv"] for row in rows
),
"source_mean_aggregate_load_tv": mean(
row["aggregate_load_tv"] for row in rows
),
}
target_tokens = sum(
source["content_tokens"] for source in sources
)
return {
"sources": len(sources),
"conditions_per_source": len(special.CONDITIONS),
"decoder_layers_executed": 27,
"moe_gates_executed": 26,
"hidden_stages": len(hidden_stages),
"target_content_tokens_per_condition": target_tokens,
"target_route_decisions": (
target_tokens
* len(special.CONDITIONS)
* 26
* 6
),
"hidden": hidden,
"routes": routes,
}
def main() -> None:
args = parse_args()
validate_args(args)
captured_at = args.captured_at or datetime.now(
timezone.utc
).isoformat()
revision_contract = behavior.download_revision_contract(
args.artifact_dir
)
special.install_control_contract()
tokenizer = AutoTokenizer.from_pretrained(
args.artifact_dir,
trust_remote_code=True,
local_files_only=True,
use_fast=True,
)
if tokenizer.pad_token_id is None:
tokenizer.pad_token_id = tokenizer.eos_token_id
if special.special_family_token_ids(tokenizer) != {
"eos": 100001,
"bos": 100000,
"x": 87,
"period": 13,
}:
raise RuntimeError("pinned tokenizer ID contract changed")
source_rows, reference = behavior.selected_sources(args, tokenizer)
for source in source_rows:
source["variants"] = {
condition: special.prior.render_boundary_variant(
tokenizer,
source["content"],
condition,
)
for condition in special.CONDITIONS
}
content_sequences = {
tuple(
source["variants"][condition]["token_ids"][position]
for position in source["variants"][condition][
"content_positions"
]
)
for condition in special.CONDITIONS
}
if len(content_sequences) != 1:
raise RuntimeError(
f"{source['id']} target token sequence is not exact "
"across conditions"
)
source["content_token_ids_sha256"] = canonical_hash(
next(iter(content_sequences))
)
if torch.cuda.is_available():
torch.cuda.empty_cache()
torch.cuda.reset_peak_memory_stats()
torch.cuda.synchronize()
load_started = time.perf_counter()
_, official_modeling = special.base.load_official_modules(
args.artifact_dir
)
model = official_modeling.DeepseekV2ForCausalLM.from_pretrained(
args.artifact_dir,
local_files_only=True,
torch_dtype=torch.bfloat16,
low_cpu_mem_usage=True,
device_map="auto",
max_memory={
0: args.gpu_memory,
"cpu": args.cpu_memory,
},
)
model.eval()
if torch.cuda.is_available():
torch.cuda.synchronize()
load_seconds = time.perf_counter() - load_started
load_peak_cuda = (
torch.cuda.max_memory_allocated()
if torch.cuda.is_available()
else None
)
input_device = model.get_input_embeddings().weight.device
capture = TraceCapture(model.config.n_routed_experts)
handles = [
model.model.embed_tokens.register_forward_hook(
capture.hidden_hook("embedding")
),
model.model.norm.register_forward_hook(
capture.hidden_hook("final_norm")
),
]
for index, layer in enumerate(model.model.layers):
handles.append(
layer.register_forward_hook(
capture.hidden_hook(f"layer_{index:02d}")
)
)
if hasattr(layer.mlp, "gate"):
handles.append(
layer.mlp.gate.register_forward_hook(
capture.gate_hook(index)
)
)
traced_sources = []
try:
for source in source_rows:
unpadded = [
source["variants"][condition]["token_ids"]
for condition in special.CONDITIONS
]
prompt_lengths = [len(row) for row in unpadded]
batch_tokens = max(prompt_lengths)
padded = [
[int(tokenizer.pad_token_id)]
* (batch_tokens - len(row))
+ row
for row in unpadded
]
masks = [
[0] * (batch_tokens - len(row))
+ [1] * len(row)
for row in unpadded
]
positions = condition_positions(
source["variants"],
batch_tokens,
)
capture.start(positions, batch_tokens)
input_ids = torch.tensor(
padded,
dtype=torch.long,
device=input_device,
)
attention_mask = torch.tensor(
masks,
dtype=torch.long,
device=input_device,
)
if torch.cuda.is_available():
torch.cuda.reset_peak_memory_stats()
torch.cuda.synchronize()
started = time.perf_counter()
with torch.inference_mode():
output = model.model(
input_ids=input_ids,
attention_mask=attention_mask,
use_cache=False,
output_attentions=False,
output_hidden_states=False,
return_dict=True,
)
if torch.cuda.is_available():
torch.cuda.synchronize()
elapsed = time.perf_counter() - started
peak = (
torch.cuda.max_memory_allocated()
if torch.cuda.is_available()
else None
)
if output.last_hidden_state.shape[:2] != input_ids.shape:
raise RuntimeError(
"final hidden batch/sequence shape does not match input"
)
expected_hidden = {
"embedding",
*(f"layer_{index:02d}" for index in range(27)),
"final_norm",
}
expected_routes = {
f"layer_{index:02d}"
for index in range(1, 27)
}
if set(capture.hidden) != expected_hidden:
raise RuntimeError(
f"hidden stages mismatch: {set(capture.hidden)}"
)
if set(capture.routes) != expected_routes:
raise RuntimeError(
f"router layers mismatch: {set(capture.routes)}"
)
content_tokens = len(
positions[special.CONDITIONS[0]][
"target_content"
]
)
traced_sources.append(
{
key: value
for key, value in source.items()
if key not in {"content", "variants"}
}
| {
"prompt_tokens_by_condition": {
condition: prompt_lengths[index]
for index, condition in enumerate(
special.CONDITIONS
)
},
"batch_prompt_tokens": batch_tokens,
"content_tokens": content_tokens,
"content_token_ids_sha256": source[
"content_token_ids_sha256"
],
"boundary_crossing_tokens_by_condition": {
condition: source["variants"][condition][
"boundary_crossing_tokens"
]
for condition in special.CONDITIONS
},
"forward_seconds": elapsed,
"peak_cuda_memory_allocated_bytes": peak,
"hidden_stages": capture.hidden,
"router_layers": capture.routes,
}
)
finally:
for handle in handles:
handle.remove()
device_map = getattr(model, "hf_device_map", {})
peaks = [
source["peak_cuda_memory_allocated_bytes"]
for source in traced_sources
if source["peak_cuda_memory_allocated_bytes"] is not None
]
result = {
"schema_version": 1,
"captured_at": captured_at,
"model": {
"repo": "deepseek-ai/DeepSeek-V2-Lite-Chat",
"revision": behavior.MODEL_REVISION,
"checkpoint_identity": "SFT Chat",
"architecture": type(model).__name__,
"dtype": "bfloat16",
"download_revision_contract": revision_contract,
"files": {
name: {
"bytes": (args.artifact_dir / name).stat().st_size,
"sha256": behavior.sha256(
args.artifact_dir / name
),
}
for name in behavior.MODEL_FILES
},
},
"tokenizer_contract": {
"length": len(tokenizer),
"vocab_size": tokenizer.vocab_size,
"all_special_ids": tokenizer.all_special_ids,
"pad_token_id": tokenizer.pad_token_id,
"conditions": special.FACTORS,
},
"source_contract": {
**reference,
"domains": args.domains,
"per_domain": args.per_domain,
"sources": len(source_rows),
"full_source_text_used": True,
"target_scope": (
"byte-identical interior content tokens; tokens whose "
"offset crosses the content boundary are excluded"
),
},
"trace_contract": {
"conditions": list(special.CONDITIONS),
"scopes": list(SCOPES),
"edge_pairs": EDGE_PAIRS,
"decoder_layers": 27,
"moe_gate_layers": list(range(1, 27)),
"experts": model.config.n_routed_experts,
"top_k": model.config.num_experts_per_tok,
"use_cache": False,
"raw_hidden_tensors_saved": False,
"raw_route_ids_saved": False,
"load_vectors_saved": True,
"hashes_cover_exact_bfloat16_hidden_and_route_values": True,
},
"execution": {
"python": platform.python_version(),
"torch": torch.__version__,
"transformers": transformers.__version__,
"accelerate": accelerate.__version__,
"safetensors": safetensors.__version__,
"platform": platform.platform(),
"gpu": (
torch.cuda.get_device_name(0)
if torch.cuda.is_available()
else None
),
"gpu_memory_limit": args.gpu_memory,
"cpu_memory_limit": args.cpu_memory,
"pytorch_cuda_alloc_conf": os.environ.get(
"PYTORCH_CUDA_ALLOC_CONF"
),
"input_device": str(input_device),
"device_map": device_map,
"load_seconds": load_seconds,
"forward_seconds": sum(
source["forward_seconds"]
for source in traced_sources
),
"load_peak_cuda_memory_allocated_bytes": load_peak_cuda,
"peak_cuda_memory_allocated_bytes": max(
[load_peak_cuda, *peaks]
),
"process_max_rss_kib": resource.getrusage(
resource.RUSAGE_SELF
).ru_maxrss,
},
"sources": traced_sources,
"summary": aggregate_trace(traced_sources),
"claim_boundary": [
"The trace observes one fixed SFT Chat checkpoint, not the Base checkpoint.",
"Target comparisons exclude boundary-crossing tokens and require exact token IDs.",
"Router and hidden associations do not establish mediation or capability causality.",
"CPU in hf_device_map is offload residency, not proof of CPU matrix execution.",
"Prompt-only use_cache=False traces are not generation-time KV or serving traces.",
],
}
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(
json.dumps(result, ensure_ascii=False, indent=2) + "\n",
encoding="utf-8",
)
payload = args.output.read_bytes()
print(
json.dumps(
{
"output": str(args.output),
"sha256": hashlib.sha256(payload).hexdigest(),
"bytes": len(payload),
"sources": len(traced_sources),
"decoder_layers": 27,
"moe_gates": 26,
"target_route_decisions": result["summary"][
"target_route_decisions"
],
"load_seconds": load_seconds,
"forward_seconds": result["execution"][
"forward_seconds"
],
"peak_cuda_memory_allocated_bytes": result[
"execution"
]["peak_cuda_memory_allocated_bytes"],
},
ensure_ascii=False,
indent=2,
)
)
if __name__ == "__main__":
main()
@@ -24,6 +24,7 @@ import ast
import gzip
import hashlib
import json
import os
import platform
import re
import resource
@@ -933,6 +934,9 @@ def main() -> None:
),
"gpu_memory_limit": args.gpu_memory,
"cpu_memory_limit": args.cpu_memory,
"pytorch_cuda_alloc_conf": os.environ.get(
"PYTORCH_CUDA_ALLOC_CONF"
),
"input_device": str(input_device),
"device_map": device_map,
"parameter_bytes_by_runtime_parameter_device": (