跳到正文
LLM 推理

参考

在本地运行

除最后一章外,每章都配一个自包含的 Python 文件:两秒内跑完,打印它测到的数字,并断言本章给出的结论。依赖只有 NumPy 一个。最后一章是 TypeScript,用 Node 运行。

环境准备

terminalbash
git clone <this repository>
cd learn-llm-inference-from-scratch

python3 -m venv .venv && source .venv/bin/activate
pip install numpy

Python 3.10 或更新版本,不需要 GPU,不用下载模型,也不用 PyTorch。前几章用的是词级 bigram 模型,没有权重也能把引擎机制端到端跑一遍。到了架构本身要紧的地方(S03),代码写的就是真实架构,只是权重随机初始化。

运行某一章

terminalbash
python code/s01_generation_loop.py
python code/s06_paged_attention.py
python code/s14_speculative_decoding.py

python code/run_all.py

有两个文件不只是打印。s19_server.py --serve 会在 localhost:8000 上启动一个真正的 OpenAI 兼容流式服务器,只用标准库,不依赖 FastAPI。s20_complete_engine.py 则把所有部件装到一起,在你的机器上跑一次留一消融实验。

服务器bash
python code/s19_server.py --serve &

curl -N http://127.0.0.1:8000/v1/chat/completions \
  -H 'content-type: application/json' \
  -d '{"messages":[{"role":"user","content":"hi"}],"max_tokens":8}'

curl http://127.0.0.1:8000/metrics

文件清单

章节文件行数
S01生成循环code/s01_generation_loop.py137
S02分词code/s02_tokenizer.py232
S03Transformer 前向传播code/s03_transformer.py251
S04采样code/s04_sampling.py206
S05KV 缓存code/s05_kv_cache.py205
S06PagedAttentioncode/s06_paged_attention.py283
S07前缀缓存code/s07_prefix_caching.py263
S08量化code/s08_quantization.py252
S09连续批处理code/s09_continuous_batching.py244
S10调度器code/s10_scheduler.py442
S11分块 Prefillcode/s11_chunked_prefill.py190
S12FlashAttentioncode/s12_flash_attention.py183
S13算子融合与 CUDA Graphcode/s13_cuda_graphs.py185
S14投机解码code/s14_speculative_decoding.py188
S15结构化输出code/s15_structured_output.py338
S16专家混合(MoE)code/s16_moe.py152
S17张量并行与流水线并行code/s17_parallelism.py216
S18Prefill/Decode 分离部署code/s18_disaggregation.py186
S19服务层code/s19_server.py363
S20完整的引擎code/s20_complete_engine.py421
S21用 Python 重写 picoLMcode/s21_picolm.py495
S22用 TypeScript 写 mini-picoLMcode/src/lib/minipicolm/4018

有几个文件会 import 更早的文件:s07 用到 s06 的 block 管理器,s20 两个都用。所以请在 code/ 目录内运行,或者交给 run_all.py,它会替你设好工作目录。

再进一步:换上真实权重

想让同样的代码跑真实模型,最小的一步是:用 fp16 的 Llama-3.2-1B,transformers 只负责加载权重,前向传播仍用你自己在 S03 里写的那份,再在 temperature 0 下与 HuggingFace 的 generate() 对拍。如果前二十个 token 一致,说明 RoPE 布局和注意力掩码都对了,而这两处恰恰最容易出错。