CHAPTER 23附录 A 源码入口地图
16 分钟阅读 · 3,480 字
四块:引擎 / 服务层 / 网关 / 压测台与取证工具,外加部署与切换工具。
所有行号是 2026-10-20 02:00(北京)当场 grep -n 核实的,对应文件 mtime 见各表末列。
总览 §7 的入口地图是本书起点,但它的行号已经漂移过至少一次 —— 别拿旧文档的行号直接用(18 章"文档与现实不符")。
A.0 先记住:两个仓库、两条 lane
|
快道 A |
普道 B |
仓库(CWD) |
/home/cloud/SSEStraBed |
/home/cloud/Strata → /home/cloud/SSEStraBed(2026-10-21 起) |
| 引擎二进制 |
deploy/engines/bin/mtpvarlen-20261021d/strata |
同一个 |
| profile 名 |
ssebed(active-a.env 指定) |
ssebed(active-b.env,2026-10-21 13:46 起) |
| 引擎配置文件 |
deploy/engines/profiles/ssebed/strata-a.json |
deploy/engines/profiles/ssebed/strata-b.json |
| 端口 / GPU / 核段 |
8091 / GPU0 / taskset 0-15 |
8092 / GPU1 / taskset 38-53 |
engine_version(10-21 19:03 实测) |
ssebed-0.1.38-b5 |
ssebed-0.1.38-b5 |
| 服务层 Python |
同一个文件:Strata/serve/server.py |
同上 |
2026-10-21 修订:两条 lane 现在跑同一份代码、同一个二进制(--mtp-varlen 版本),
差别只剩「GPU / 核段 / 端口 / profile 文件」。
这对阅读源码是好事:本附录后面的行号对两条 lane 都成立,不需要再区分 legacy 侧偏移。
现态以 deploy/engines/profiles/ssebed/*.json 与 python3 deploy/switch_engine.py status 为准。
两个仓库的 C++ 源码是同源分叉:Strata/src/ 与 SSEStraBed/src/ 目录结构完全一致,
ssebed 侧多了中文注释与后续改动。所以同一件事在两个仓库里的行号不同
(例:prefill yield 在 Strata/src/program/generate.cpp:6331,在 SSEStraBed/.../generate.cpp:6681)。
本书一律以 SSEStraBed(快道在跑的那套) 为主口径,并标注 legacy 侧差异。
A.1 引擎(C++)
A.1.1 目录分组
SSEStraBed/
├─ src/program/generate.cpp ← 唯一入口:CLI + serve 主循环 + 批槽(8091 行)
├─ src/core/ ← 会话、缓存、专家、图、层、设备
├─ src/kernels/ ← CUDA / CPU kernel 与 parity 对照测试
├─ src/prefill/ ← prefill 路径(GDN 递归、GEMM、MoE fused)
├─ src/spec/ ← 投机解码:drafter / controller / draft policy
├─ src/artifact/ ← GGUF 读取、反量化
├─ src/ngram/ ← PLE(n-gram 嵌入)读取
├─ src/plan/ src/platform/ ← 计划器、内存与文件层
├─ include/strata/ ← 头文件
├─ third_party/llama.cpp/ ← 词表与 tokenizer 来源(CMake 的 -DSTRATA_GGML_DIR)
├─ build/strata ← 生产二进制(+ BUILD.json,见 16 章)
└─ deploy/ ← 切换工具(A.5)
| 目录 |
关键文件(行数) |
管什么 |
src/core/ |
session.cpp (1289)、conversation_snapshot.cpp (276)、conversation_memory.cpp (56)、conversation_state.cpp、conversation_checked.hpp |
会话停车(park)与检查点(12 章) |
src/core/ |
expert_cache.cpp (849)、expert_source.cpp、peer_experts.cpp (626)、remote_experts.cpp (632) |
专家缓存层:本机 arena、对等卡、跨卡远端(11 章) |
src/core/ |
layer.cpp (2414)、layout.cpp (292)、graph.cpp、weights.cpp、device.cu、pinned.cu |
层图、权重布局、设备与锁页内存 |
src/core/ |
mtp.cpp (1215)、verify.cpp (2001) |
MTP 草稿与校验(10 章) |
src/prefill/ |
prefill.cpp (2721)、kernels.cu、gemm.cu、gdn_rec_parity.cu、moe_fused.cu、moe_mmq.cu |
prefill(09 章的瓶颈本体) |
src/spec/ |
suffix_drafter.cpp (170)、controller.cpp (148)、draft_policy.cpp (196) |
后缀 drafter 与草稿策略(批槽 MTP 的 v1 实现) |
src/kernels/cuda/ |
s2_expert_grouped.cu、verify_kernels.cu、iq_kernels.cu、sampler.cu |
批窗口 kernel(GMAX 在这里) |
src/kernels/*_parity.cpp |
30+ 个 *_parity.cpp |
CPU 参考实现 vs GPU kernel 的逐值对照(改 kernel 必跑) |
A.1.2 generate.cpp 锚点(SSEStraBed,8091 行 / 564,119 B / mtime 2026-10-18 17:08 UTC = 10-19 01:08 北京)
| 找什么 |
行 |
说明 |
int main(int argc, char** argv) |
1243 |
唯一入口 |
| 选项结构体默认值 |
284–447 |
附录 B 的"引擎默认"全在这一段(pool_workers=0 :284、vram_reserve_mib=700 :365、spec=0 :389、batch=0 :393、batch_groups=1 :399、batch_mtp=false :400、prompt_cache=6 :439、conversation_cache_mib=0 :440、conversation_cache_min_free_mib=2560 :442、prompt_cache_every=16384 :444、prompt_cache_root=2048 :447) |
CLI 解析(--pack / --max-context / --kv / --pool-workers …) |
1285–1560 |
逐个 else if (a == "--xxx") |
--prefill / --spec / --mtp / --layer-split / --serve |
1405 / 1420 / 1427 / 1435 / 1439 |
|
缓存旋钮 --prompt-cache* / --conversation-cache-* |
1442–1459 |
|
--peer-device |
1506(声明与互斥注释 :327) |
|
--peer-device 与 --layer-split 互斥检查 |
1945 |
`if (o.peer_device >= 1 && (!o.layer_split.empty() |
serve 模式前置校验(缺 --spec/--mtp/--prefill 直接 return 2) |
4501 |
硬约束 11 |
| 单 GPU 上的 layer split 与 parking 互斥 |
1604–1607 |
conversation parking does not support a layer split on one GPU → return 2 |
校验窗口预算打印(spec/batch/chains → verify_max_t) |
4902 |
|
--batch 初始化槽位(每 stage 独占一张卡) |
4966–4982 |
--batch needs each stage on its own GPU |
chain_off(链捕获显存不足 → 永久降级为单 token 窗口) |
5732 / 5759 / 5783 / 5849 |
10 章的降级机制 |
--batch-groups 校验 |
5867 |
需要 layer split 且整除 --batch |
BCHAIN <slot> <L> <tokens> 调试命令 |
6008–6021 |
单槽链窗口 |
STRATA_PREFILL_YIELD_CHUNKS / _STEPS |
6681–6692 |
09 章的 prefill 让出旋钮(legacy 侧 :6331–6342) |
| 批槽准入(admission)失败日志 |
7092 / 7122–7125 |
|
⚠️ 行数已经变过:SESSION-BD7E62ED-DIAGNOSIS-2026-10-19.md 记的是 7862 行 / 514,308 B / mtime 2026-10-18 06:13;
现在是 8091 行 / 564,119 B / mtime 2026-10-18 17:08 UTC(= 10-19 01:08 北京)。
差的是 10-18 晚那轮中文注释清理(备份在 ~/archive/patches/generate-cpp-cn-cleanup-2026-10-18/)。
引用该文件的行号前先 grep -n 重新锚定(A.6)。
A.1.3 硬编码常量(2026-10-21 由两个扩到六个)
| 常量 |
位置 |
值 |
为什么重要 |
kVerifyMaxT |
include/strata/kernels/verify_kernels.hpp:28 |
8 |
校验窗口一次最多 8 个 token(--spec 4 是生产值);L_max = min(4, 8/S) 的来源 |
GMAX |
src/kernels/cuda/s2_expert_grouped.cu:1360 |
8 |
一个批窗口内路由到同一专家的条目上限;static_assert(GMAX >= kVerifyMaxT);超过就静默丢条目(10 章、19 章 P2) |
kStagingBlobs |
include/strata/core/verify.hpp:357 |
16 |
一帧最多 16 个未命中专家走 PCIe 快档,其余落 CPU —— 并发天花板的真正入口(07 章 §7.12) |
MAXT |
src/kernels/cpu/kq_avx2.cpp:43、include/strata/kernels/cpu/expert.hpp:169 |
8 |
CPU 专家池一次处理的 token 上限 |
dma_src[64] |
src/core/expert_source.cpp:3384 |
64 |
单层 PCIe DMA 源指针数组 |
| 批槽上限 |
generate.cpp:2960-2961 |
2…8 |
--batch 的合法区间由 kVerifyMaxT 决定 |
A.1.4 2026-10-21 重新锚定(generate.cpp 现 8177 行 / 570,258 B / mtime 10-21 04:38 UTC)
上面 A.1.2 那张表是 10-19 口径,已经漂移 7–95 行。这一节是 10-21 当场 grep -n 的结果,
只列这两轮新增/最常被引用的锚点:
| 找什么 |
行 |
说明 |
int main(...) |
1250 |
10-19 记为 1243(+7) |
| 选项默认值区段 |
286–459 |
pool_workers=0 :286、vram_reserve_mib=700 :367、spec=0 :391、batch=0 :395、batch_groups=1 :401、batch_mtp=false :402、pcie_frac=-1 :413、prompt_cache=6 :444、conversation_cache_mib=0 :445、prompt_cache_every=16384 :449、prompt_cache_root=2048 :452、short_read=64 :459 |
--batch 合法区间检查 |
2960–2961 |
2 <= N <= kVerifyMaxT |
chain_off 声明与四处置位 |
5749 / 5825 / 5849 / 5933 |
10-19 记为 5732/5759/5783/5849 |
L_max(行预算被并发除) |
5781 |
min(chain_rows_per_slot, max(1, kVerifyMaxT/S)) |
sl.sampled → 整组退化 |
5821–5824 |
sl.sampled 在 7192 置位(!req_sp.greedy) |
strata batch: 汇总行 |
5711–5725 |
槽全空时打印(batch_on() :5615) |
step-stats 出口 |
5706(batch/chain)、6600(prefill) |
STRATA_STEP_STATS=<path> |
STRATA_PREFILL_YIELD_CHUNKS/_STEPS |
6767–6791 |
10-19 记为 6681–6692 |
| prompt 读取的四种走法 |
6810–6837 |
read_windows(窗口)/ sp.run 分段(:6831)/ sp.run 整段(:6837)/ lend+refill |
--short-read 门与 read_windows |
459 / 6547 / 6554 / 6826 |
09 章 §9.9、21 章 M3 |
--pcie-frac 探测与默认 |
413 / 2064–2077 |
启动打印 PCIe probe ... -> pcie_frac 0.55 |
主循环 for (;;) |
6075 |
全引擎唯一的服务循环 |
--batch-groups > 1 的流水线路径 |
5816 |
piped(pump_fn) |
server.py 侧同样复核过:self.ctl :412、generate_batched :654、取锁 :670、
释放 :747 / :792(10-19 记为 :1268 的 self.fifo 是 --batch 0 时代的主锁)。
A.2 服务层(Python,Strata/serve/)
两条 lane 共用这一份代码(15 章 §15.4)——所以事故 3 的修复一次覆盖两条通道(在两次重启之后)。
A.2.1 server.py(3459 行 / 199,662 B / mtime 2026-10-19 07:26 UTC = 15:26 北京)
| 找什么 |
行 |
class Engine(Protocol) / MockEngine / 各种引擎异常(EngineDied EngineSilent ModelBusy GpuBusy …) |
85–140 |
启动叙事(把引擎日志翻译成人话:experts_loading_words、narrate_start) |
224–298 |
class StrataEngine(fork 引擎子进程、读 BUILD.json、HTTP 通信) |
308 |
class Vision(常驻 strata-vision sidecar) |
954 |
engine_args(cfg)(配置 JSON → 引擎 CLI) |
1095 |
learned_profile_args / hip_visible / child_env / vision_env |
1122 / 1145 / 1161 / 1179 |
class ByteTokenizer / class Detokenizer |
1195 / 1220 |
Detokenizer.push 剥离 SPECIAL_MARKER(事故 3 的输出侧) |
1237–1248 |
class Service(fit_max_tokens :1254、escape_special :1260、stops_while_reasoning :1263、api_monitor :1285) |
1251 |
engine_identity() / engine_version() |
1330 / 1343 |
metrics() / v1_status()(prompt_escapes :1640、engine_version :1665) |
1606 / 1645 |
Service.prepare(套模板 + 转义 + 采样参数) |
1708 |
超窗 400 文案 #545(fit_max_tokens 分支) |
1754–1764 |
stops_while_reasoning += 1 |
1977 |
OpenAI 流式(首/末 chunk 注入 engine_version) |
2127–2186 |
| Anthropic 事件流 |
2256–2354 |
make_handler(HTTP 路由) |
2355 |
路由:/metrics 2528、/api/requests(仅 api_monitor 开)2533、/health 2558、/status 2563、/slots 2594–2601、/v1/status 2601、/unload 2619、/load 2627、/v1/chat/completions 2664、/v1/messages 2666 |
见左 |
main()(argparse 与配置合并;--fit-max-tokens :3248、--api-monitor :3257、fit_max_tokens 落地 :3339) |
3229 |
/slots 的代码证据(盲区清单第一条):server.py:2594-2601 构造的是
slot = {"id": 0, "n_ctx": ..., "is_processing": busy},返回 [slot] —— 永远只有一个合成槽,
与引擎的 4 个批槽无关。这不是 bug 记录,是"引擎状态模型是单路的"的直接证据。
A.2.2 frontend.py(729 行 / 35,205 B / mtime 2026-10-18 06:07 UTC = 14:07 北京)
| 找什么 |
行 |
class ChatTemplate(jinja2 套模板) |
33 |
DEFAULT_CONTROL_TOKENS |
68 |
SPECIAL_MARKER(一个 U+2063 INVISIBLE SEPARATOR 字符) |
67 |
control_token_literals(tokenizer)(取 GGUF token_type==3 CONTROL 类,本 pack 27 个) |
78–95 |
escape_special_tokens(字面量首字符后插 marker:literal[0] + SPECIAL_MARKER + literal[1:]) |
98–109 |
_escape_value(只转义值,不转义 dict key) |
111 |
sanitize_prompt_inputs(覆盖 content / reasoning_content / tool_calls.arguments / tool description+parameters;不碰图片 source) |
143–204 |
openai_to_messages / anthropic_to_messages |
313 / 350 |
parse_tool_call / class OutputParser(事故 5 的 state=call / scall=None 丢弃路径在这里) |
484 / 517 |
A.2.3 服务层测试
serve/test_server.py(125 个用例,10-18 实测 124/125 通过)、test_detok.py、test_lifecycle.py、
test_mcp.py、test_monitor.py、test_security.py、test_structured.py、test_winjob.py。
跑法:cd ~/Strata && python -m unittest serve.test_server(switch-engine dev test 会自动跑它)。
A.3 网关(rag-proxy/)
| 找什么 |
文件:行 |
默认配置(rag_enabled :65、chars_per_token :102、image_tokens :110、retry_on_overfit :113) |
rag_proxy.py:56–140 |
load_config |
:143 |
log() 用裸 time.strftime('%H:%M:%S') → 前缀是 UTC |
:168–169 |
upstreams() / pick_upstream() / route_upstream(model, key)(模型 ID + 会话粘性,不 failover) |
:187 / :193 / :201 |
上界估算器 _CJK_RE / text_tokens_upper(系数 CJK 1.05 / digit 1.05 / other 0.70) |
:214 / :219–231 |
count_image_blocks / image_allowance(一张图按 1024 计,count_tokens 只数 1 个 pad) |
:233 / :249 |
est_prompt_tokens / count_margin / clamp_max_tokens |
:253 / :260 / :265 |
thinking_guard / refit_thinking_budget |
:286 / :319 |
overfit_room / patch_max_tokens(旧的"压 max_tokens 盲重试"路径) |
:342 / :355 |
overfit_info / overfit_error(10-19 新增:把 400 改写成 prompt is too long: N > M + 中文 hint) |
:376 / :397 |
count_tokens(调 serve 的 /v1/{chat/completions,messages}/count_tokens 精确计数) |
:456–488 |
切块与检索:parse_turns :599、split_unit :644、chunk_turn :704、chunk_messages :728、chunk_messages_legacy :739、embed_texts :766、rerank :836、recent_window :990、render_block :1054、expand_context :1074、build_memory_block :1123、assemble :1255 |
见左 |
会话与聊天存储:class Session :863、get_session :923、session_key :941、chats_load/save :1452/:1473 |
见左 |
class Handler(请求主流程;no_rag 透传分支 :2044–2078、窗口预检 :2061–2069、快速透传 :2104) |
:1493 |
lane_label / _authorized / 并发登记 reg_open reg_close(/concurrency 的数据源) |
:2209 / :2220 / :2229 / :2244 |
| 文档抽取(PDF/DOCX/XLSX/CSV,扫描 PDF 走页面图,按剩余预算头尾截断) |
doc_extract.py(698 行) |
请求留档(infer.db + infer-segs/,MinIO 前缀 infer) |
infer_store.py(881 行) |
| 网关测试 |
test_window_guard.py(10-19 新增,ALL PASS)、test_doc_extract.py、test_infer_store.py、test_rag_proxy.py、test_concurrency.py、test_session_isolation.py、test_thinking_guard.py、mock_upstream.py |
行号漂移实例:CONTEXT-COUNT-BILLING-2026-10-19.md 引用 rag_proxy.py:1715-1720(盲重试)与 :372(思考预算)。
现在盲重试在 :1768、思考预算在 :286/:319;只有 clamp_max_tokens 的 :265 没变。
该报告写于当天 14–15 点,文件 mtime 是 15:28 北京 —— 报告引用的是修复前的行号。
A.4 压测台与取证工具
A.4.1 压测台 ~/bench/(详见 13 章)
| 文件 |
用途 |
run.py / speedtest.py / channel_test.py |
速度与通道测试 |
speed_matrix.sh / mtp_ab.sh / single_ab.py / freeze_ab.py |
并发矩阵与 A/B 交替(红线 6 的执行工具) |
ctx1m_full.sh / run_guard.sh |
1M 精度全量套件(默认 --model strata-b,红线 2) |
niah_run.py / babilong_run.py / needle_bench.py / longctx_test.py |
长上下文精度(14.8 的数字来源) |
dual_lane_test.py |
直连 8091/8092 的双 lane 对照 |
window_guard_live.py |
10-19 窗口守卫的现网验证 |
parse_engine_log.py / analyze.py / matrix_table.py / charts.py |
引擎日志解析与报表(12 章 §12.7 的取证方法) |
lib/client.py lib/prompts.py lib/toolsets.py lib/images.py lib/sampler.py |
公共库(key 从文件读,不硬编码) |
runs/ data/ answers/ report/ |
原始数据与产出 |
| 文件 |
用途 |
batch_test.py |
逐 token 一致性(GEN vs BGEN,红线 6;需独占 GPU) |
batch_chain_test.py / batch_chain_live_test.py / chain_prod_repro.py |
批槽 MTP 链 |
conversation_cache_*.py(parity / growth / soak / isolation / disabled / http_smoke) |
停车缓存全套 |
parking_test.py / early_close_test.py |
停车与提前结束 |
strata_tokenizer.py / strata_pack.py / gguf_reader.py / gguf_writer.py / pack_layer.py |
离线 tokenizer 与打包 |
calibrate.py / canonical_xcheck.py / iq_fixture.py |
标定与交叉校验 |
strata-trace.sh / strata_mcp.py |
追踪与 MCP |
| 文件 |
用途 |
scan_claude_early_stop.py --date <部署日> |
扫某天某通道的早停请求(事故 3 的复查工具) |
repro_claude_early_stop.py minimal|replay(用 python3 -I 跑) |
最小复现与真实请求回放(18.4) |
minio-upload.py / minio-backup.py |
MinIO 备份(17.3) |
~/tools_dev/comment_check/gen1/ |
事故 4 的注释草稿与 apply_cn.py(含已知 schema bug) |
A.5 部署与切换
| 找什么 |
位置 |
| 引擎切换实现(1084 行;锚点见 16 章) |
SSEStraBed/deploy/switch_engine.py、包装 SSEStraBed/deploy/switch-engine |
| 切换手册 |
SSEStraBed/deploy/README-switch.md、SSEStraBed/切换引擎用户手册.md |
| 薄分发器 |
Strata/run-iq3_xxs-a.sh、-b.sh、run-iq3_xxs.sh(单实例布局) |
| 布局切换 / 自动恢复 |
Strata/layout.sh、Strata/layout-restore.sh、状态文件 ~/deploy/layout.mode(当前 dual) |
| 进程守护 |
~/deploy/supervisord.conf(15 章 §15.2) |
| 引擎 profile 与 active env |
~/deploy/engines/profiles/{legacy,ssebed}/、active-a.env(+.prev)、switch.lock |
| 构建计数器与身份 |
每条 lane 一套:SSEStraBed/build/{build-number.txt,BUILD.json}(当前 1 / ssebed-0.1.38-b1)、Strata/build/{build-number.txt,BUILD.json}(当前 0 / legacy-0.1.38-b0);Strata/engine/BUILD.json 是预置引擎包的另一份 |
| 前端工程与发布 |
Strata/serve/webapp/(Vue3+Vite)、webapp/tools/deploy.sh(不用重启引擎)、产物 Strata/serve/web/ |
A.6 怎么自己重新锚定(别信任何行号,包括本书的)
# 1) 先看文件是否变了(mtime 是 UTC,+8 才是北京时间)
stat -c '%n %s bytes mtime=%y' SSEStraBed/src/program/generate.cpp Strata/serve/server.py rag-proxy/rag_proxy.py
# 2) 用"标识符 + 语义"锚定,而不是用行号
grep -n 'int prompt_cache = ' SSEStraBed/src/program/generate.cpp
grep -n 'def prepare' Strata/serve/server.py
grep -n 'def overfit_error' rag-proxy/rag_proxy.py
# 3) 需要看上下文时按行区间读,读前确认区间真的是那段代码
sed -n '2594,2612p' Strata/serve/server.py
三条纪律(来自 18 章与 memory annotation-anchor-verification):
- 标识符存在 ≠ 代码结构存在 —— 相似度重新锚定不可信,落地前必须备份 + 严格 diff + 编译;
- 绝对路径先
ls/realpath(事故 4);
- 两个仓库同名文件行号不同(A.0),引用时永远写全路径。
A.7 本附录小结
- 引擎只有一个入口:
src/program/generate.cpp(8091 行)——CLI、serve 主循环、批槽、降级全在里面;
想改 prefill / 批槽 / 观测,先从这里找到调用点,再进 src/prefill/、src/spec/、src/core/。
- 服务层只有一份 Python(
Strata/serve/server.py + frontend.py),两条 lane 共用 ——
这就是"事故 3 修一处覆盖两通道"的原因,也是它的坑:改完必须重启两条 lane 才都生效(B 到 10-19 18:58 才跟上)。
- 网关的锚点集中在计数与改写(
text_tokens_upper / count_tokens / overfit_error / 窗口预检),
10-19 的事故与修复全在这一块。
- 压测台与取证工具是独立目录(
~/bench、Strata/tools、~/tools),不在引擎仓库里 ——
别在 SSEStraBed/ 里找压测脚本。
- 本附录所有行号 核实于 2026-10-20 02:00 北京;文件一改就漂。用 A.6 的方式重新锚定,别复制粘贴行号。