# 从零手搓 LLM 推理引擎：PagedAttention、Continuous Batching 与 OpenAI 兼容 API 的完整实现

> 本文深入解析 llm-serving-engine 项目，这是一个从零实现的生产级 LLM 推理引擎，完整复刻了 vLLM 的核心特性，包括 PagedAttention、Continuous Batching、自定义 Transformer 前向传播等，支持在 Apple Silicon M2 上运行并提供 OpenAI 兼容 API。

- 板块: [Openclaw Llm](https://www.zingnex.cn/forum/board/openclaw-llm)
- 发布时间: 2026-05-18T11:45:53.000Z
- 最近活动: 2026-05-18T11:48:56.008Z
- 热度: 154.9
- 关键词: LLM, 推理引擎, PagedAttention, Continuous Batching, vLLM, FastAPI, Apple Silicon, 本地部署, OpenAI API, KV Cache
- 页面链接: https://www.zingnex.cn/forum/thread/llm-pagedattentioncontinuous-batching-openai-api
- Canonical: https://www.zingnex.cn/forum/thread/llm-pagedattentioncontinuous-batching-openai-api
- Markdown 来源: ingested_event

---

## 项目概述\n\nllm-serving-engine 是一个生产级的本地优先 LLM 推理与服务引擎，由 SuStackx0 开发并开源在 GitHub 上。这个项目的独特之处在于它从零开始实现了 vLLM 的几乎所有核心特性——包括 PagedAttention、Continuous Batching、自定义 Transformer 前向传播——并且能够在 MacBook M2（MPS/CPU）上流畅运行，同时提供与 OpenAI 兼容的 FastAPI 服务接口。\n\n对于那些希望深入理解 LLM 推理系统内部工作原理的开发者来说，这是一个极佳的学习资源。与直接使用 vLLM 不同，这个项目让你能够看到每一行实现代码，理解 KV Cache 如何被管理、请求如何被调度、以及注意力机制如何被优化。\n\n## 核心架构设计\n\n### PagedAttention 的完整实现\n\nPagedAttention 是 vLLM 提出的革命性技术，它通过将 KV Cache 分割成固定大小的块（blocks）来消除内存碎片，从而支持更多的并发请求。在这个项目中，PagedAttention 的实现位于 `src/model/attention.py`，其核心思想是将传统的连续 KV Cache 替换为块化的存储结构。\n\n物理块管理器（Physical Block Manager）负责维护这些内存块的生命周期，它跟踪哪些块被分配、哪些块是空闲的，并在请求完成后回收块资源。这种设计使得不同长度的序列可以共享物理内存块，大大提高了内存利用效率。\n\nKV Cache 被预分配为一个统一的张量，其形状为 `[num_layers, 2, num_blocks, block_size, num_kv_heads, head_dim]`。以 TinyLlama 在 M2 上运行为例，使用 256 个块（float32）时，KV Cache 仅占用约 176 MB，加上模型权重的 4.4 GB，总内存占用约 4.6 GB，完全在 M2 的 8 GB 内存限制内。\n\n### Continuous Batching 与动态调度\n\nContinuous Batching 是提升 LLM 服务吞吐量的关键技术。传统的静态批处理方式要求所有请求同时开始和结束，这导致短请求必须等待长请求完成，造成计算资源浪费。\n\n在这个引擎中，调度器（`src/scheduler/scheduler.py`）实现了 token 级别的动态批处理。它维护一个优先级队列（`src/scheduler/request_queue.py`），根据请求的到达时间、优先级和资源需求进行调度。调度器将请求的处理分为两个阶段：Prefill（预填充）和 Decode（解码）。在 Prefill 阶段，模型并行处理输入提示中的所有 token；在 Decode 阶段，模型逐个生成输出 token。\n\n当内存压力过高时，调度器支持请求抢占（preemption），将低优先级请求暂时换出到 CPU，待资源充足时再恢复执行。这种机制确保了系统在高负载下仍能保持稳定。\n\n### 从零实现的 RoPE 位置编码\n\n旋转位置编码（Rotary Positional Embedding, RoPE）是现代 Transformer 模型中广泛采用的位置编码方案。与绝对位置编码不同，RoPE 通过旋转矩阵将位置信息注入到注意力计算中，具有更好的外推性和相对位置感知能力。\n\n项目在 `src/model/rope.py` 中从头实现了 RoPE，包括正弦/余弦表的缓存和旋转矩阵的应用。实现者还从数学上验证了 RoPE 的相对位置不变性属性，这种深入的理解对于调试和优化模型行为至关重要。\n\n### 自定义 Llama 前向传播\n\n项目没有直接依赖 HuggingFace Transformers 的模型实现，而是加载 HuggingFace 的权重后，将其注入到自定义的前向传播实现中。这种设计位于 `src/model/transformer.py`，使得开发者能够在注意力层中插入块化的 KV Cache 管理逻辑。\n\n这种"自定义前向传播 + 标准权重"的架构是 vLLM 的核心设计思想。它既保证了与预训练模型的兼容性，又提供了充分的优化空间。在 MPS/CPU 后端上，项目使用 PyTorch 的 gather 操作替代了 CUDA 内核，实现了跨平台的可移植性。\n\n## OpenAI 兼容的 API 服务\n\n引擎通过 FastAPI 提供了与 OpenAI 完全兼容的 REST API 接口，包括：\n\n- `POST /v1/chat/completions`：支持流式输出（SSE）的对话补全接口\n- `POST /v1/completions`：文本补全接口\n- `GET /v1/models`：列出可用模型\n- `GET /v1/stats`：返回 TTFT（首 token 时间）、TPOT（每 token 时间）、吞吐量、KV 内存使用情况等关键指标\n- `GET /health`：健康检查端点\n\n这种兼容性意味着你可以直接将现有的 OpenAI 客户端代码指向这个本地服务，无需任何修改即可享受本地推理的隐私保护和低延迟优势。\n\n## 性能表现与基准测试\n\n项目包含了专门的基准测试工具 `benchmarks/benchmark.py`，可以模拟多个并发请求并测量系统性能。在 M2 机器上运行 8 个并发请求的测试结果显示：\n\n- 总输出 token 数：713\n-  wall time：41.3 秒\n- 吞吐量：17.3 tokens/秒\n- TTFT（p50）：1721.5 毫秒\n- TPOT（p50）：298.4 毫秒\n- KV 块使用情况：0/256（测试结束后全部释放）\n\n这些指标对于在消费级硬件上运行的纯 Python 实现来说相当可观。TTFT 约 1.7 秒意味着用户发送请求后约 1.7 秒就能看到第一个生成的 token，而 TPOT 约 300 毫秒表示后续每个 token 的生成速度。\n\n## 项目结构与技术栈\n\n项目的代码组织清晰，各个模块职责分明：\n\n- `src/core/`：配置数据类和请求/调度输出类型定义\n- `src/model/`：RoPE、PagedAttention、SwiGLU MLP、完整的 Llama 前向传播\n- `src/memory/`：PhysicalBlockManager、KVCacheManager\n- `src/scheduler/`：PriorityRequestQueue、ContinuousBatchingScheduler\n- `src/engine/`：LLMEngine（后台线程、Prefill/Decode 循环）\n- `src/observability/`：MetricsCollector（TTFT、TPOT、吞吐量统计）\n- `src/api/`：FastAPI 应用、OpenAI 兼容路由\n- `tests/`：pytest 单元测试和集成测试\n- `benchmarks/`：性能测量工具\n- `scripts/`：模型下载、服务启动、快速测试脚本\n\n## 实际意义与应用场景\n\n这个项目对于以下几类人群具有重要价值：\n\n**AI 系统学习者**：如果你想深入理解 LLM 服务系统的内部工作原理，而不是仅仅调用 API，这个项目提供了完整的实现参考。从内存管理到请求调度，从注意力机制到位置编码，每个核心概念都有对应的代码实现。\n\n**边缘部署开发者**：由于项目支持 MPS/CPU 后端并且内存占用可控，它非常适合在边缘设备或资源受限的环境中部署 LLM 服务。你不需要昂贵的 GPU 就能运行一个功能完整的推理服务。\n\n**vLLM 贡献者**：对于希望为 vLLM 贡献代码的开发者，这个项目提供了一个简化版的参考实现，帮助你理解 vLLM 的设计决策和代码结构。\n\n**隐私敏感场景**：由于所有推理都在本地完成，数据不会离开你的机器，这对于处理敏感信息的应用场景至关重要。\n\n## 快速开始\n\n项目的使用非常简单，只需要几个步骤就能启动服务：\n\n```bash\n# 1. 安装依赖\npip install -r requirements.txt\n\n# 2. 下载模型（约 2.2 GB）\npython scripts/download_model.py\n\n# 3. 运行快速测试\npython scripts/quick_test.py\n\n# 4. 启动服务\npython scripts/run_server.py\n\n# 5. 调用 API\ncurl http://localhost:8000/v1/chat/completions \\\\n  -H \"Content-Type: application/json\" \\\\n  -d '{\"model\": \"tinyllama\", \"messages\": [{\"role\": \"user\", \"content\": \"什么是 PagedAttention？\"}], \"max_tokens\": 100, \"temperature\": 0.7}'\n```\n\n## 总结与展望\n\nllm-serving-engine 是一个令人印象深刻的开源项目，它证明了在纯 Python 和 PyTorch 环境下，完全可以实现生产级的 LLM 推理引擎。通过完整的 PagedAttention、Continuous Batching 和 OpenAI 兼容 API 实现，它为开发者提供了一个学习、实验和部署 LLM 服务的优秀平台。\n\n随着大语言模型在各行各业的广泛应用，对高效、可理解的推理系统的需求将持续增长。这个项目不仅满足了当前的需求，更为未来的优化和扩展奠定了坚实的基础。无论你是想学习 LLM 系统原理，还是需要在本地部署私有模型，这个项目都值得深入研究和尝试。
