Skip to content

Part 6: 练习

1. GPU 后端 + 总结

练习 1:Metal 管线追踪

题目:描述一个 Metal kernel 从源码到执行的完整路径。

参考答案(先自己尝试,再展开查看)
1. .metal 源码 → 编译为 MTLLibrary(GPU 字节码)
   id<MTLLibrary> lib = [device newLibraryWithSource:...];

2. 从 library 提取 kernel 函数
   id<MTLFunction> fn = [lib newFunctionWithName:@"kernel_name"];

3. 创建计算管线(编译为 GPU 可执行的微码)
   id<MTLComputePipelineState> pipe = [device newComputePipelineStateWithFunction:fn ...];

4. 创建命令缓冲区
   id<MTLCommandBuffer> cmd = [queue commandBuffer];

5. 编码计算命令(设置 buffer、分发线程组)
   [encoder setComputePipelineState:pipe];
   [encoder setBuffer:buf offset:0 atIndex:0];
   [encoder dispatchThreadgroups:grid threadsPerThreadgroup:group];

6. 提交执行
   [cmd commit];
   [cmd waitUntilCompleted];

练习 2:CPU vs GPU 对比

题目:对于矩阵乘法 [4096, 2048] × [2048, 4096](约 160 亿 FLOP),比较 CPU 和 GPU 的处理方式。

参考答案(先自己尝试,再展开查看)
输出矩阵大小: 4096 × 4096 = 16,777,216 个元素
每个元素: 2048 次乘加 = 4096 FLOP
总 FLOP: 16.8M × 4096 ≈ 68.7B

CPU (8 核):
  每个 core 处理 ~2.1M 元素
  串行计算每个元素
  时间: ~68.7B FLOP / (8 × ~100 GFLOP/s) ≈ 0.09s

GPU (M3 Max, ~4000 核):
  每个 core 处理 ~4,200 元素
  所有 core 并行执行
  时间: ~68.7B FLOP / (~13 TFLOP/s) ≈ 0.005s

加速比: ~18× (理论值,实际受内存带宽限制)

练习 3:知识串联

题目:用一个请求的完整生命周期串联所有主题学到的知识。

"用户发送 POST /v1/chat/completions 请求,得到流式回复。"

参考答案(先自己尝试,再展开查看)
HTTP:    服务器接收请求(socket → recv → 解析 HTTP)
HTTP:    JSON 解析请求体(手写递归下降解析器)
HTTP:    解析 messages、tools、temperature 等字段
分词:    Chat 模板渲染(特殊 token 组装)
分词:    BPE 分词(text → token IDs)
服务:    检查磁盘 KV cache(SHA1 匹配前缀)
加载:    模型权重通过 mmap 加载(零拷贝)
加载:    Metal GPU 框架初始化
推理:    Prefill 阶段(所有 prompt token 通过 43 层)
架构:    每层访问 weights_bind 绑定的权重指针
加载:    权重从 GGUF 张量数据中读取
架构:    量化权重解码(IQ2_XXS/Q2_K → float)
架构:    Self-Attention 计算(Q·K^T → softmax → V 加权)
架构:    KV Cache 写入(raw sliding window + MLA 压缩)
架构:    MoE 前向传播(路由 → 6 专家 → SwiGLU)
推理:    RoPE 旋转位置编码
推理:    Decode 循环(自回归,逐 token 生成)
采样:    采样(temperature + top-p → 选择 token)
分词:    Token 解码(ID → 文本)
HTTP:    SSE 流式发送给客户端
服务:    KV cache 保存到磁盘

今日学习检查清单

  • 能描述 Metal kernel 从源码到执行的路径
  • 理解 GPU 并行计算的优势
  • 理解零拷贝 MTLBuffer 的工作原理
  • 能解释 Flash Attention 的核心思想
  • 能用完整请求生命周期串联 15 天的知识
  • 能总结 ds4.c 的 6 大设计哲学

延伸挑战

挑战 1(中级):Metal vs CPU 性能对比

分别用 ./ds4(Metal 加速)和 make cpu && ./ds4(纯 CPU)运行相同的 prompt。对比 prefill 速度和 decode 速度。GPU 加速比是多少?在哪些阶段加速最明显?

挑战 2(高级):端到端请求追踪(capstone 预习)

lldb attach 到 ds4-server,在 client_mainds4_tokenize_rendered_chatprefill_layer_major_cpusample_full_vocabsse_chunk 五个函数设断点。发送一个 HTTP 请求,记录每个断点的调用栈和参数。写一份完整的"一个 HTTP 请求的一生"调试报告。