CalcGuide · 技术博客主页 / 一页纸学习计划
🔥极高

LLM 推理与性能:从推理引擎到吞吐延迟优化

分类:数据与人工智能 · 路径:docs/topics/llm-inference-and-perf/README.md

#llm-inference#vllm#tgi#ollama#performance

对比 vLLM/TGI/Ollama,掌握 KV cache、量化和吞吐延迟调优

父主题

大语言模型应用:从 Prompt 到 RAG 与 Agent 的工程实践

子主题(0)



LLM 推理与性能:从推理引擎到吞吐延迟优化

0. 元信息

1. 学习路线

推理请求与基准方法
  → Ollama 本地服务
  → TGI 服务化推理
  → vLLM continuous batching
  → KV cache 与显存
  → 量化
  → 吞吐/延迟压测与调优

2. 阶段周数分配(1~2 周,每天 1.5~2 小时)

阶段1 周方案2 周方案备注
1. 引擎对比0.25 周0.5 周vLLM / TGI / Ollama 定位与部署
2. 量化0.25 周0.5 周FP16 / INT8 / INT4 与质量权衡
3. KV cache 与显存0.25 周0.5 周显存预算、prefix cache、连续批处理
4. 性能调优0.25 周0.5 周压测、调参、报告

分阶段概述

1 周方案每天 2 小时;2 周方案每天 1.5 小时,多留 2 天做量化与 KV cache 实验。基准条件不一致会让比较失效——所有结论必须记录硬件、模型、量化、上下文和并发。

3. 阶段表

阶段核心知识实践产出可观察学会标准
1. 引擎对比vLLM、TGI、Ollama 的定位、API、部署边界三引擎对比表能在相同模型/请求下说明选择依据
2. 量化FP16/BF16、GPTQ/AWQ、bitsandbytes、精度权衡量化前后基准能同时报告质量、显存、延迟和吞吐变化
3. 性能调优batching、并发、max tokens、prefix cache、P95压测报告与调参记录能定位瓶颈,避免用单一平均值下结论

4. 第一周(每天 1.5~2 小时)

环境约定:本子主题统一使用 Python 3.11+ 与 python -m venv .venv;压测脚本用纯 Python(参考 §9.7.1);硬件记录写在 notes/perf/hardware.md(GPU 型号 / 显存 / CUDA / 驱动)。API key 通过 export ANTHROPIC_API_KEY=... 共享 .env 模板:父主题 attachments/.env.example 含 Anthropic / OpenAI / Voyage / Qdrant / Ollama / OTel / Langfuse 全套变量;本地 cp ../../attachments/.env.example .env 后填值,.env 加入 .gitignore,加载用 python-dotenv禁止把真实 key 提交到仓库或写入 trace / 日志。 注入;本地推理用 ollama serve 起端点(默认 http://localhost:11434)。

任务当天交付自检
Day 1ollamacurl,拉取 qwen2.5:7b 并起 OpenAI-compatible 端点;写最小对话脚本notes/perf/day1.md + curl 命令curl http://localhost:11434/v1/models 返回 qwen2.5:7b;对话脚本拿到一次回复
Day 2写压测脚本:测 10 条短 prompt,记录 TTFT(首 token 延迟)/ TPOT(每 token 延迟)/ 总耗时 / 完成 token 数notes/perf/day2.md + perf/bench.py10 条样本跑完;TTFT / TPOT / 总耗时三项均有统计;输出含 model / precision / context
Day 3同模型对比 Ollama(CPU / GPU)、vLLM(如果 GPU 可用):写 notes/perf/engines.md 三引擎对比表notes/perf/engines.md三引擎在同一 prompt / 同一 max_tokens 下可比;显存 / 吞吐 / 延迟差异可解释
Day 4量化档位对比:用本地 7B 模型跑 FP16 与 INT4(ollama show --modelfile 看量化),记录显存与延迟;用同一组中文评测 prompt 验证质量不掉档notes/perf/quant.mdFP16 与 INT4 的显存差 ≥ 30%;中文 prompt 输出无明显退化
Day 5加并发:用 asyncioconcurrent.futures 跑 4 / 8 并发,记录 P50 / P95 / P99 / 错误率notes/perf/concurrency.mdP95 相比单请求没有数量级飙升;错误率 < 1%
Day 6max_tokens / temperature / top_p:观察对首 token 与总延迟的影响;保存调参记录notes/perf/tuning.md至少 3 组参数对比;TTFT 与 TPOT 变化幅度有解释
Day 7综合压测报告:把 6 天数据汇总到 report.md,含硬件 / 模型 / 量化 / 上下文 / 并发 / TTFT / TPOT / P95 / 吞吐;做一次”误归因”复盘(说明哪些结论其实是配置差异而非引擎差异)notes/perf/report.md报告按模板填齐;每条结论附原始日志;至少指出 1 条可能误归因的判断

第一周复盘要求

每日把硬件、模型、量化、上下文、并发、TTFT / TPOT / P95 原始数据写到 notes/perf/ 对应日期的 md;Week 1 结束前用 30 分钟复盘:哪些参数被误以为是引擎差异?哪些瓶颈其实在 prefill 而非 decode?

5. 阶段通用验收

  1. 不看答案独立重写压测脚本与显存预算估算;
  2. 用自己的话解释 prefill / decode / KV cache / continuous batching 的瓶颈差异;
  3. 画”请求 → prefill → KV cache → decode → batch → 指标”的数据流图;
  4. 测试冷启动、长短请求混合、高并发、超长 context、显存不足 5 类边界;
  5. 准备至少 3 组模型 / 量化 / 并发组合并贴出实际数据;
  6. 记录 TTFT、TPOT、总延迟、P50/P95/P99、tokens/s、显存占用;
  7. 能修改已有基准(换模型 / 换量化 / 改并发)并复现压测报告。

交付存放:第 3 项的图、第 5 项的实际数据、第 6 项的指标统一存到 notes/perf/ 或 README 对应章节,便于复盘与综合项目引用。

6. 最终验收(学完 1~2 周后)

API key 配置与回退方案

7. 综合项目

首选:推理引擎选型与压测报告(必做:三引擎对比 + 多档量化 + 多并发压测 + report.md + 至少 2 条”误归因”识别)。

备选:本地 RAG 推理优化(必做:固定 RAG pipeline + 量化 + prefix cache + 压测 + 报告)。

任何综合项目都必须包含:

  1. 需求说明:要解决的问题、用户故事、输入输出约定(含冷启动、长短请求混合、超长 context);
  2. 数据流与引擎选择理由:为什么选这套引擎 / 量化 / 并发;记录权衡;
  3. 算法与策略说明:显存预算、KV cache 复用、continuous batching、prefix cache 触发条件;
  4. 模块化源码bench.py / vram.py / tuning.py 等职责单一;
  5. 边界与安全测试:冷启动、超长 context、显存不足、并发打满、量化档位误选;
  6. 运行说明make bench 或清晰 python -m ... 命令,注明环境变量与依赖;
  7. README:项目介绍、运行步骤、目录结构、复盘(踩过的坑、可改进点);
  8. 评测与复盘记录notes/retrospective.md(用时、难点、收获、下一步)。

notes/ 与 README 存放规范

所有”画图(数据流 / 压测拓扑)“和”贴原始数据”类交付物统一存放在项目根目录的 notes/ 子目录或 README 的对应章节;提交时一并带上,避免散落在聊天或临时文件里。综合项目的 notes/ 至少包含:

本主题贡献(Loop 6-D · llm-applications / llm-inference-and-perf)

本主题把”显存预算、量化档位、KV cache 复用、continuous batching、prefix cache”五条独立工程线拧成一条验收闭环,输出可被父主题与下游子主题直接复用的推理压测包。

3 项核心职责

4 项交付物

  1. 显存预算表 + 量化决策树vram.py(按模型 + 量化 + 并发算峰值显存)+ 决策树(FP16 → INT8 AWQ → INT4 GPTQ 三档选型),附 A100 / H100 / L40S 三卡实测。
  2. 压测脚本 + 报告bench.py(输入 prompt 长度 / max_tokens / 并发 / 量化 4 维扫描),输出 TTFT / TPOT / latency / tokens/s / 显存峰值 5 项指标表。
  3. 引擎 + 部署配置:vLLM / TGI / TensorRT-LLM 三选一的 deployment.yaml(含 continuous batching + prefix cache + max_num_seqs),附引擎选型理由(吞吐 / 延迟 / 易用性)。
  4. 边界测试 + 必读交付:冷启动 / 超长 context / 显存不足 / 并发打满 / 量化档位误选 5 类各 1 例,配 notes/design.md(硬件 + 模型 + 量化 + 并发)+ notes/retrospective.md

3 个验收指标

8. 推荐开源资料(按角色分工,避免堆链接)

阶段角色资料链接用法
1本地推理Ollama 文档https://ollama.com/docs本地 OpenAI-compatible 端点;学习 / 验证用
1服务化推理vLLM 文档https://docs.vllm.ai/continuous batching、PagedAttention;高吞吐首选
1服务化推理TGI 文档https://huggingface.co/docs/text-generation-inferenceHugging Face 系服务化;Rust 实现,部署与 vLLM 各有取舍
2量化bitsandbyteshttps://github.com/bitsandbytes-foundation/bitsandbytesINT8 / INT4 量化的工程基础;MIT 许可证
2量化AutoGPTQhttps://github.com/AutoGPTQ/AutoGPTQGPTQ 量化参考;使用前确认 LICENSE
2量化AutoAWQhttps://github.com/casper-hansen/AutoAWQAWQ 量化参考;使用前确认 LICENSE
3KV cachevLLM PagedAttention 论文https://arxiv.org/abs/2309.06180理解 KV cache 分页与显存节省原理
3推理原理《LLM Inference Unveiled》https://medium.com/@yangyou_berkeley/llm-inference-unveiled-3d-scheduling-101-9bba5bd96f3eprefill / decode 调度入门;博客参考,引用即可
4压测工具vLLM Benchmark Scripthttps://github.com/vllm-project/vllm/tree/main/benchmarksvLLM 自带 benchmark;对照自有脚本
4压测工具OpenAI Evals(性能部分)https://github.com/openai/evals评测 + 压测结合;不要直接当生产评测
通识模型查阅Hugging Face Hubhttps://huggingface.co/docs查模型卡、tokenizer、推理参数
通识API 查阅Anthropic API 文档https://docs.anthropic.com/en/api/overview查参数、token、限制与价格;用于云端对照

许可证提示:复制或参考 vLLM / TGI / bitsandbytes / AutoGPTQ / AutoAWQ 等开源仓库代码前,先打开 LICENSE 确认:vLLM(Apache-2.0)、TGI(Apache-2.0)、bitsandbytes(MIT)、AutoGPTQ(MIT)、AutoAWQ(MIT)。默认做法是读思路后自己重写,而不是复制粘贴;GPL 类代码用于商业 / 闭源项目前请逐条阅读。

硬件记录:每条压测结论必须附 {gpu, vram_gb, cuda, driver, model, quantization, context, max_tokens, concurrency},否则视为不可复现;评测集要兼顾中文与英文,避免”英文 MMLU 高分 → 中文指令微调模型其实崩盘”的归因偏差。

默认使用顺序:先用 Ollama 起本地端点 + qwen2.5:7b 跑最小对话 → 写 bench.py 测 TTFT / TPOT → 引入 vLLM / TGI 做三引擎对比 → 加 INT8 / INT4 量化对照 → 加 4 / 8 并发与 P95 → 调 max_tokens / temperature / top_p → 汇总 report.md 并做”误归因”复盘 → 复盘到 notes/retrospective.md

9. 学习资料汇聚(v0.3 自包含)

9.1 背景与动机

模型能力只是服务的一部分;推理引擎决定如何调度请求、复用 KV cache 和利用显存。性能优化必须建立可复现基准,否则吞吐提升可能以质量、尾延迟或成本恶化为代价。

9.2 概念地图

flowchart LR
  Request[请求] --> Prefill[Prefill]
  Prefill --> KV[KV cache]
  KV --> Decode[Decode]
  Decode --> Batch[批处理/调度]
  Model[模型权重] --> Quant[量化]
  Quant --> Memory[显存]
  Memory --> KV
  Batch --> Metrics[吞吐/首 token/总延迟/P95]

9.3 基础知识讲解

主推 vLLMTGIOllama 官方文档;备查量化工具和模型仓库说明。先用 Ollama 理解本地服务,再用 TGI/vLLM 做同模型基准;所有结论记录硬件、模型、量化、上下文和并发。

9.4 经典问题与经典案例

问题最简答案
显存不够减小模型/上下文、量化或分片,并重新测质量
首 token 慢优化 prefill、上下文长度、prefix cache 和批处理
解码吞吐低检查 batch、并发、GPU 利用率和 memory bandwidth
P95 抖动分离冷启动、长短请求,检查排队和 max tokens
量化后质量降用固定评测集比较,不只看主观样例
本地快、线上慢固定硬件、驱动、引擎版本和请求分布后再归因

9.5 学习难点

9.6 技术标准与接口

Entity

OpenAI-compatible endpoint、prefill/decode、KV cache、continuous batching、quantization、tokens/s、TTFT、TPOT、P95。

Scope

推理引擎负责模型服务和调度,不保证应用质量、事实性或业务安全;性能指标只在给定负载与硬件下成立。

Structure

必须掌握模型权重精度、显存占用、上下文长度、max new tokens、并发、batch、TTFT、TPOT、总延迟和吞吐。

Ecosystem

Ollama 偏本地易用;TGI 偏 Hugging Face 服务化;vLLM 偏高吞吐调度与兼容 API。版本、GPU、CUDA 和量化格式会改变结论。

Depth Tiers

L0 知道引擎存在;L1 看懂启动参数;L2 能部署并压测;L3 能定位显存/排队/批处理瓶颈;L4 能设计多模型路由和容量规划。本子主题要求 L3。

Source

vLLM、TGI、Ollama 官方文档及对应量化项目文档;版本快照日期:2026-07-28。

9.7 关键代码

9.7.1 TTFT / TPOT / tokens/s 压测采集

# 9.7.1 OpenAI-compatible endpoint 压测:TTFT、TPOT、tokens/s
import time
import urllib.request
import json

ENDPOINT = "http://localhost:11434/v1/chat/completions"  # Ollama 示例
PROMPT = "用一句话解释 KV cache。"
CONCURRENCY = 4
N_REQ = 8

def one_request() -> tuple[float, float, int]:
    body = json.dumps({
        "model": "qwen2.5:7b",
        "messages": [{"role": "user", "content": PROMPT}],
        "stream": False,
    }).encode()
    req = urllib.request.Request(ENDPOINT, data=body, headers={"Content-Type": "application/json"})
    t0 = time.perf_counter()
    with urllib.request.urlopen(req, timeout=60) as r:
        first = time.perf_counter()
        data = json.loads(r.read())
    t1 = time.perf_counter()
    out = data.get("choices", [{}])[0].get("message", {}).get("content", "")
    completion_tokens = max(1, len(out))
    return (first - t0) * 1000, (t1 - first) * 1000 / completion_tokens, completion_tokens

if __name__ == "__main__":
    samples = [one_request() for _ in range(N_REQ)]
    ttft = [s[0] for s in samples]
    tpot = [s[1] for s in samples]
    print(f"TTFT mean={sum(ttft)/len(ttft):.1f}ms max={max(ttft):.1f}ms")
    print(f"TPOT mean={sum(tpot)/len(tpot):.1f}ms")

9.7.2 显存预算估算 + 量化档位对比

# 9.7.2 显存预算估算(FP16 / INT8 / INT4)
def vram_gb(params_b: float, precision_bytes: float, overhead: float = 1.2) -> float:
    """params_b: 十亿参数;precision_bytes: 2=FP16, 1=INT8, 0.5=INT4;overhead 含 KV/激活。"""
    weights = params_b * precision_bytes
    return weights * overhead

if __name__ == "__main__":
    p = 7.0  # 7B 模型
    for name, b in [("FP16", 2), ("INT8", 1), ("INT4", 0.5)]:
        print(f"{name}: {vram_gb(p, b):.1f} GB")

9.7.3 真实可运行:Anthropic SDK + 简单的并发吞吐测试

# 9.7.3 用 Anthropic SDK 测一次非流式 + 流式的首 token / 总延迟
# 运行:export ANTHROPIC_API_KEY=...; python perf_anthropic.py
import os
import time
import anthropic

client = anthropic.Anthropic()
PROMPT = "用一句话回答:1+1=?"

t0 = time.perf_counter()
resp = client.messages.create(
    model="claude-haiku-4-5",
    max_tokens=64,
    messages=[{"role": "user", "content": PROMPT}],
)
t1 = time.perf_counter()
text = resp.content[0].text
in_tok = resp.usage.input_tokens
out_tok = resp.usage.output_tokens
print(f"非流式: {(t1-t0)*1000:.0f}ms, in={in_tok} out={out_tok}, text={text!r}")
# 流式测首 token
t0 = time.perf_counter()
first = None
with client.messages.stream(
    model="claude-haiku-4-5",
    max_tokens=64,
    messages=[{"role": "user", "content": PROMPT}],
) as stream:
    for event in stream:
        if getattr(event, "type", "") == "content_block_start":
            first = time.perf_counter()
            break
    stream.until_done()
t1 = time.perf_counter()
print(f"流式首 token: {((first-t0)*1000 if first else 0):.0f}ms 总耗时 {(t1-t0)*1000:.0f}ms")

10. 常见误区

11. 所有知识点分类(统一规则)

  1. 编程语言
  2. 数据结构与算法
  3. 计算机基础
  4. 工程技术
  5. Web 与后端
  6. 前端与客户端
  7. 数据与人工智能
  8. 项目与职业能力

本计划归属:数据与人工智能 主 + 工程技术 辅。


直接依赖(0)

查看知识图谱 · 热度 🔥极高