Add code long-context attention profiling grid
This commit is contained in:
@@ -33,7 +33,9 @@ max_model_len_recommendation != null
|
|||||||
selected.selected_window_stats.max_model_len_coverage[推荐值].coverage = 1.0
|
selected.selected_window_stats.max_model_len_coverage[推荐值].coverage = 1.0
|
||||||
```
|
```
|
||||||
|
|
||||||
旧记录预计 source block size 为 512、推荐 max model len 为 131072,但禁止把这两个值写死为实验事实。
|
全量审计已确认 source block size=512;development source window 若 100%
|
||||||
|
覆盖需要 262144,但正式 server cap 以 session-sampled paired cell 的实际
|
||||||
|
`ISL+OSL max` 向上对齐,不能把 full-window 262144 无条件套到低 rho cell。
|
||||||
审计会单独记录并排除 `input_length<=0` 或 `output_length<=0` 的 source
|
审计会单独记录并排除 `input_length<=0` 或 `output_length<=0` 的 source
|
||||||
行;这些行只有在 raw trace 同样显示 zero usage/empty response 时才按
|
行;这些行只有在 raw trace 同样显示 zero usage/empty response 时才按
|
||||||
“未发生模型执行”处理,不能无记录过滤。
|
“未发生模型执行”处理,不能无记录过滤。
|
||||||
@@ -89,14 +91,14 @@ python3 runs/frontier-s3-real-v0/remap_hash_blocks.py \
|
|||||||
现有 real runner 新增了三个显式环境变量,chat 默认行为不变:
|
现有 real runner 新增了三个显式环境变量,chat 默认行为不变:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
MAX_MODEL_LEN=131072 \
|
MAX_MODEL_LEN=ACTUAL_CELL_MAX_ROUNDED_UP \
|
||||||
TRACE_INPUT_ROOT=/absolute/path/to/materialized/code-cell \
|
TRACE_INPUT_ROOT=/absolute/path/to/materialized/code-cell \
|
||||||
ALLOW_SYNTHETIC_PROMPTS=true \
|
ALLOW_SYNTHETIC_PROMPTS=true \
|
||||||
OUTPUT_ROOT=/absolute/path/to/new/output \
|
OUTPUT_ROOT=/absolute/path/to/new/output \
|
||||||
bash runs/frontier-s3-real-v0/run_full_real.sh RHO_LABEL tp4_mns16 1 PORT
|
bash runs/frontier-s3-real-v0/run_full_real.sh RHO_LABEL tp4_mns16 1 PORT
|
||||||
```
|
```
|
||||||
|
|
||||||
- `MAX_MODEL_LEN` 必须等于 manifest 推荐值;
|
- `MAX_MODEL_LEN` 必须覆盖 manifest 中该 paired cell 的实际最大请求;
|
||||||
- `TRACE_INPUT_ROOT` 内必须有 `real_requests.jsonl` 和 `manifest.json`;
|
- `TRACE_INPUT_ROOT` 内必须有 `real_requests.jsonl` 和 `manifest.json`;
|
||||||
- synthetic prompt 默认拒绝,只有在 experiment card 明确降级 claim 后才设为 `true`;
|
- synthetic prompt 默认拒绝,只有在 experiment card 明确降级 claim 后才设为 `true`;
|
||||||
- runner 会在启动前扫描 paired requests,若任何 `ISL+OSL` 超 cap 立即失败。
|
- runner 会在启动前扫描 paired requests,若任何 `ISL+OSL` 超 cap 立即失败。
|
||||||
|
|||||||
79
runs/frontier-code-trace-v0/check_longctx_profile_repeats.py
Normal file
79
runs/frontier-code-trace-v0/check_longctx_profile_repeats.py
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Check fresh-process repeat stability for the code long-context grid."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args() -> argparse.Namespace:
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("--first", type=Path, nargs="+", required=True)
|
||||||
|
parser.add_argument("--second", type=Path, nargs="+", required=True)
|
||||||
|
parser.add_argument("--output", type=Path, required=True)
|
||||||
|
parser.add_argument("--max-relative-difference", type=float, default=0.05)
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def load(paths: list[Path]) -> dict[tuple[int, str], dict]:
|
||||||
|
rows: dict[tuple[int, str], dict] = {}
|
||||||
|
for path in paths:
|
||||||
|
payload = json.loads(path.read_text())
|
||||||
|
for row in payload["rows"]:
|
||||||
|
if row.get("error"):
|
||||||
|
raise ValueError(
|
||||||
|
f"{path}: failed profile row {row['config']['batch_spec']}"
|
||||||
|
)
|
||||||
|
key = (
|
||||||
|
int(row["tensor_parallel_size"]),
|
||||||
|
str(row["config"]["batch_spec"]),
|
||||||
|
)
|
||||||
|
if key in rows:
|
||||||
|
raise ValueError(f"duplicate row {key}")
|
||||||
|
rows[key] = row
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
args = parse_args()
|
||||||
|
first = load(args.first)
|
||||||
|
second = load(args.second)
|
||||||
|
if first.keys() != second.keys():
|
||||||
|
raise ValueError(
|
||||||
|
f"repeat key mismatch: first_only={sorted(first.keys()-second.keys())}, "
|
||||||
|
f"second_only={sorted(second.keys()-first.keys())}"
|
||||||
|
)
|
||||||
|
comparisons = []
|
||||||
|
for key in sorted(first):
|
||||||
|
left = float(first[key]["mean_time"])
|
||||||
|
right = float(second[key]["mean_time"])
|
||||||
|
relative = abs(left - right) / ((left + right) / 2)
|
||||||
|
comparisons.append(
|
||||||
|
{
|
||||||
|
"tp": key[0],
|
||||||
|
"batch_spec": key[1],
|
||||||
|
"first_mean_s": left,
|
||||||
|
"second_mean_s": right,
|
||||||
|
"relative_difference": relative,
|
||||||
|
"pass": relative <= args.max_relative_difference,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
maximum = max(item["relative_difference"] for item in comparisons)
|
||||||
|
payload = {
|
||||||
|
"schema": "frontier-code-longctx-repeat-check-v1",
|
||||||
|
"threshold": args.max_relative_difference,
|
||||||
|
"maximum_relative_difference": maximum,
|
||||||
|
"status": "PASS" if maximum <= args.max_relative_difference else "FAIL",
|
||||||
|
"comparisons": comparisons,
|
||||||
|
}
|
||||||
|
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
args.output.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n")
|
||||||
|
print(json.dumps({"status": payload["status"], "max": maximum}))
|
||||||
|
if payload["status"] != "PASS":
|
||||||
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -67,10 +67,15 @@ strict decode-only 必须同时具备:
|
|||||||
|
|
||||||
### G2:`max_model_len` data gate
|
### G2:`max_model_len` data gate
|
||||||
|
|
||||||
候选 cap 固定为 `40960/65536/98304/131072/262144`,选能 **100% 覆盖选中窗口 `ISL+OSL`** 的最小值。规则:
|
source-window audit 先用 `40960/65536/98304/131072/262144` 给出完整
|
||||||
|
窗口上界;真实 server 则使用能 **100% 覆盖该 rho 实际 paired requests
|
||||||
|
的 `ISL+OSL`** 的最小 16-token 对齐值。规则:
|
||||||
|
|
||||||
- 若 max≤131072,主路径使用 131072 或更小的审计推荐值;
|
- sampling 只按 session-coherent `sampling_u`,不得按 token length 过滤;
|
||||||
- 若存在 >131072 请求,不允许悄悄过滤。优先验证 262144;若 runtime 不可行,必须预注册过滤比例,并把 claim 改为“≤131072 子群”;
|
- full source window 的 cap 用于记录 workload envelope,不强迫低 rho cell
|
||||||
|
为未被抽中的 outlier 预留 KV capacity;
|
||||||
|
- 若某 paired cell max≤131072,使用 131072 或更小的对齐值;超过
|
||||||
|
131072 时按该 cell 实际 max 向上对齐,而不是直接跳到 262144;
|
||||||
- Frontier 的 trace max tokens、predictor max tokens/request、vLLM `--max-model-len` 三处使用同一个 manifest 值。
|
- Frontier 的 trace max tokens、predictor max tokens/request、vLLM `--max-model-len` 三处使用同一个 manifest 值。
|
||||||
|
|
||||||
### G3:prompt 与 prefix fidelity
|
### G3:prompt 与 prefix fidelity
|
||||||
@@ -87,7 +92,7 @@ strict decode-only 必须同时具备:
|
|||||||
|
|
||||||
现有 profile-v5 的 KV context 上界约 32k,对 code 不足。根据 development window 的 uncached-ISL 分布生成 profile-v6-code-longctx:
|
现有 profile-v5 的 KV context 上界约 32k,对 code 不足。根据 development window 的 uncached-ISL 分布生成 profile-v6-code-longctx:
|
||||||
|
|
||||||
- full chunk:`q8k`,context 至少覆盖 32k/48k/64k/80k/96k/112k/120k;
|
- full chunk:`q8k`,context 至少覆盖 40k/56k/72k/88k/104k/120k/128k;
|
||||||
- tail chunk:从真实 `ISL mod 8192` 的 p50/p90 选择 2–4k/4–6k 代表点;
|
- tail chunk:从真实 `ISL mod 8192` 的 p50/p90 选择 2–4k/4–6k 代表点;
|
||||||
- TP1/2/4 分开采集,复测 `q1ks8k/q8ks32k` anchor;
|
- TP1/2/4 分开采集,复测 `q1ks8k/q8ks32k` anchor;
|
||||||
- 每点至少两次 fresh-process repeat;CV≤5%,anchor drift≤10%;
|
- 每点至少两次 fresh-process repeat;CV≤5%,anchor drift≤10%;
|
||||||
@@ -203,3 +208,23 @@ mode-specific:
|
|||||||
- code trace 来自 GLM5.1 业务,serving model 是 Qwen3-30B;若无原 prompt text,测试只能保持 shape/prefix 结构,不能证明内容相关 routing fidelity;
|
- code trace 来自 GLM5.1 业务,serving model 是 Qwen3-30B;若无原 prompt text,测试只能保持 shape/prefix 结构,不能证明内容相关 routing fidelity;
|
||||||
- `max_model_len=128k/256k` 解决的是接入上界,不自动解决 32k 以上 profile 外推;
|
- `max_model_len=128k/256k` 解决的是接入上界,不自动解决 32k 以上 profile 外推;
|
||||||
- strict decode-only 只测 decode engine;完整 PD 分离还需要单独建模 prefill、KV transfer、backpressure 与 KV-ready arrival。
|
- strict decode-only 只测 decode engine;完整 PD 分离还需要单独建模 prefill、KV transfer、backpressure 与 KV-ready arrival。
|
||||||
|
|
||||||
|
## 执行记录(2026-07-23)
|
||||||
|
|
||||||
|
- fleet probe:dash1–dash4 均为 8×H20;32 张卡 memory.used=0、
|
||||||
|
utilization=0、无 compute process、uncorrected ECC=0;
|
||||||
|
- 两个 formatted trace 都严格满足 512-token source hash contract;
|
||||||
|
- 0513:2,108,130 个有效请求、6090 个 zero-usage source 行;稳定
|
||||||
|
development window=`[3480,7140)`,61min、1,078,928 请求;
|
||||||
|
- 0529:1,977,423 个有效请求、6031 个 zero-usage source 行;冻结为
|
||||||
|
held-out,稳定候选 window=`[2640,6240)`;
|
||||||
|
- development window:ISL p50/p90/p99/max =
|
||||||
|
20,051/88,224/125,803/202,371;OSL p50/p90/p99/max =
|
||||||
|
78/758/6449/131,072;`ISL+OSL max=202,745`;
|
||||||
|
- full-window 131072 coverage=99.399%,262144 coverage=100%。但
|
||||||
|
session sampling 的候选 `rho<=0.0032` 实际 max total=137,016,因此
|
||||||
|
primary server cap 将按最终 cell max 对齐,不为未抽中的 202k outlier
|
||||||
|
直接预留 262k;
|
||||||
|
- source 无 Qwen-aligned prompt/token IDs。raw canonical prompt 使用 GLM
|
||||||
|
token contract,不能同时保持 Qwen token content 与 trace ISL;本 campaign
|
||||||
|
采用 synthetic Qwen tokens 保持 length/hash/prefix shape,并降级内容 claim。
|
||||||
|
|||||||
80
runs/frontier-code-trace-v0/run_flashattn_code_longctx.sh
Normal file
80
runs/frontier-code-trace-v0/run_flashattn_code_longctx.sh
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Long-context FlashAttention profile grid for the code-trace campaign.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
TP="${TP:?TP must be set to 1, 2, or 4}"
|
||||||
|
case "${TP}" in
|
||||||
|
1|2|4) ;;
|
||||||
|
*) echo "ERROR: invalid TP=${TP}" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
OUTPUT_ROOT="${OUTPUT_ROOT:?OUTPUT_ROOT must be set}"
|
||||||
|
MAX_MODEL_LEN="${MAX_MODEL_LEN:-147456}"
|
||||||
|
VENV_ROOT="${VENV_ROOT:-/home/admin/cpfs/wjh/venvs/vllm-0.20.0-cu129-workload-regime-v2}"
|
||||||
|
VLLM_SOURCE="${VLLM_SOURCE:-/home/admin/cpfs/wjh/agentic-kv/third_party/vllm_v20_build}"
|
||||||
|
MODEL="${MODEL:-/home/admin/cpfs/wjh/models/Qwen/Qwen3-30B-A3B}"
|
||||||
|
CAMPAIGN_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROFILE_SCRIPT="${CAMPAIGN_ROOT}/../frontier-qwen30-vllm020-profile-v1/profile_vllm020_flashattn.py"
|
||||||
|
|
||||||
|
# Development window:
|
||||||
|
# ISL p90=88,224, p99=125,803; sampled rho<=0.0032 max total=137,016.
|
||||||
|
# Tail query distribution modulo 8192:
|
||||||
|
# p10=495, p25=1477, p50=3594, p75=5917, p90=7246.
|
||||||
|
# The full-chunk grid reaches 131,072 tokens of existing context; tail shapes
|
||||||
|
# cover query-size variation at representative long contexts.
|
||||||
|
BATCH_SPECS=(
|
||||||
|
q8ks48k q8ks64k q8ks80k q8ks96k q8ks112k q8ks128k q8ks136k
|
||||||
|
q512s128k q2ks66k q4ks100k q6ks134k
|
||||||
|
q1ks8k q512s4k
|
||||||
|
)
|
||||||
|
|
||||||
|
mkdir -p "${OUTPUT_ROOT}/logs" "${OUTPUT_ROOT}/provenance" "${OUTPUT_ROOT}/raw"
|
||||||
|
exec > >(tee -a "${OUTPUT_ROOT}/logs/code-longctx-grid.log") 2>&1
|
||||||
|
|
||||||
|
IFS=',' read -r -a GPU_IDS <<< "${CUDA_VISIBLE_DEVICES:?one allocated fleet GPU is required}"
|
||||||
|
if [[ "${#GPU_IDS[@]}" -ne 1 ]]; then
|
||||||
|
echo "ERROR: expected exactly one GPU, got ${CUDA_VISIBLE_DEVICES}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
test -x "${VENV_ROOT}/bin/python"
|
||||||
|
test -f "${VLLM_SOURCE}/benchmarks/attention_benchmarks/runner.py"
|
||||||
|
test -f "${MODEL}/config.json"
|
||||||
|
test -f "${PROFILE_SCRIPT}"
|
||||||
|
|
||||||
|
echo "PROFILE_LAUNCH_ECHO host=$(hostname) gpu=${CUDA_VISIBLE_DEVICES} tp=${TP} max_model_len=${MAX_MODEL_LEN} specs=${BATCH_SPECS[*]}"
|
||||||
|
date -u +"START_UTC=%Y-%m-%dT%H:%M:%SZ"
|
||||||
|
nvidia-smi --query-gpu=index,name,driver_version,memory.used,utilization.gpu \
|
||||||
|
--format=csv,noheader
|
||||||
|
git -C "${CAMPAIGN_ROOT}/../.." rev-parse HEAD \
|
||||||
|
> "${OUTPUT_ROOT}/provenance/aituner.commit"
|
||||||
|
git -C "${VLLM_SOURCE}" rev-parse HEAD \
|
||||||
|
> "${OUTPUT_ROOT}/provenance/vllm-source.commit"
|
||||||
|
sha256sum "${PROFILE_SCRIPT}" "${BASH_SOURCE[0]}" \
|
||||||
|
> "${OUTPUT_ROOT}/provenance/source.sha256"
|
||||||
|
uv pip freeze --python "${VENV_ROOT}/bin/python" \
|
||||||
|
> "${OUTPUT_ROOT}/provenance/pip-freeze.txt"
|
||||||
|
printf '%s\n' "${BATCH_SPECS[@]}" \
|
||||||
|
> "${OUTPUT_ROOT}/provenance/batch-specs.txt"
|
||||||
|
printf '%s\n' "${MAX_MODEL_LEN}" \
|
||||||
|
> "${OUTPUT_ROOT}/provenance/max-model-len.txt"
|
||||||
|
|
||||||
|
timeout --signal=TERM --kill-after=30s 1800 \
|
||||||
|
"${VENV_ROOT}/bin/python" "${PROFILE_SCRIPT}" \
|
||||||
|
--vllm-source "${VLLM_SOURCE}" \
|
||||||
|
--model "${MODEL}" \
|
||||||
|
--output "${OUTPUT_ROOT}/raw/flashattn-code-longctx-tp${TP}.json" \
|
||||||
|
--tp "${TP}" \
|
||||||
|
--batch-specs "${BATCH_SPECS[@]}" \
|
||||||
|
--warmup-iters 5 \
|
||||||
|
--repeats 10 \
|
||||||
|
--max-model-len "${MAX_MODEL_LEN}" \
|
||||||
|
--profile-kv-update
|
||||||
|
|
||||||
|
test -s "${OUTPUT_ROOT}/raw/flashattn-code-longctx-tp${TP}.json"
|
||||||
|
sha256sum "${OUTPUT_ROOT}/raw/flashattn-code-longctx-tp${TP}.json" \
|
||||||
|
"${OUTPUT_ROOT}/provenance"/* > "${OUTPUT_ROOT}/artifacts.sha256"
|
||||||
|
nvidia-smi --query-gpu=index,name,memory.used,utilization.gpu --format=csv,noheader
|
||||||
|
date -u +"END_UTC=%Y-%m-%dT%H:%M:%SZ"
|
||||||
|
echo "FLASHATTN_CODE_LONGCTX_COMPLETE tp=${TP} cases=${#BATCH_SPECS[@]}"
|
||||||
@@ -37,6 +37,7 @@ def parse_args() -> argparse.Namespace:
|
|||||||
)
|
)
|
||||||
parser.add_argument("--warmup-iters", type=int, default=3)
|
parser.add_argument("--warmup-iters", type=int, default=3)
|
||||||
parser.add_argument("--repeats", type=int, default=5)
|
parser.add_argument("--repeats", type=int, default=5)
|
||||||
|
parser.add_argument("--max-model-len", type=int, default=40960)
|
||||||
parser.add_argument("--device", default="cuda:0")
|
parser.add_argument("--device", default="cuda:0")
|
||||||
parser.add_argument("--profile-kv-update", action="store_true")
|
parser.add_argument("--profile-kv-update", action="store_true")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
@@ -115,7 +116,7 @@ def main() -> None:
|
|||||||
trust_remote_code=False,
|
trust_remote_code=False,
|
||||||
dtype="bfloat16",
|
dtype="bfloat16",
|
||||||
seed=0,
|
seed=0,
|
||||||
max_model_len=40960,
|
max_model_len=args.max_model_len,
|
||||||
)
|
)
|
||||||
cache_config = CacheConfig(block_size=config.block_size, cache_dtype="auto")
|
cache_config = CacheConfig(block_size=config.block_size, cache_dtype="auto")
|
||||||
cache_config.num_gpu_blocks = max_num_blocks
|
cache_config.num_gpu_blocks = max_num_blocks
|
||||||
@@ -124,7 +125,7 @@ def main() -> None:
|
|||||||
scheduler_config = SchedulerConfig(
|
scheduler_config = SchedulerConfig(
|
||||||
max_num_seqs=256,
|
max_num_seqs=256,
|
||||||
max_num_batched_tokens=8192,
|
max_num_batched_tokens=8192,
|
||||||
max_model_len=40960,
|
max_model_len=args.max_model_len,
|
||||||
is_encoder_decoder=False,
|
is_encoder_decoder=False,
|
||||||
enable_chunked_prefill=True,
|
enable_chunked_prefill=True,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user