FDE Training · Module 03
03
LLM 推理与大模型调用
模块 03 · LLM 推理与大模型调用
本章目标:掌握 AI 工程的第一站——把大模型"部署起来"和"调起来"。分两块:一是本地/私有化推理部署(vLLM 等),二是通过 API 调用各种大模型并踩平 token、上下文、流式、重试的坑。这是 2026 FDE 的核心分水岭之一。
3.1 先搞懂推理是啥
- 训练:把海量数据"喂"给模型,让它学会;开满 GPU,跑很久。
- 推理:模型已经学会,你给它一句话,它给你答案;这就是客户每天都在用的环节。
- FDE 主要关心推理:怎么让"已经训好的模型"又快又稳地出答案,还能省钱。
关键指标(面试必背):
- 吞吐量(Throughput):单位时间能出多少 token。
- 延迟(Latency):一个请求从进去到出第一个字/全部字多久。
- TTFT(Time To First Token):到第一个字的延迟(流式体验的关键)。
- 显存占用:模型装不装得下、并发能开多大。
3.2 推理框架:vLLM 是主力(TGI / TensorRT-LLM 了解)
3.2.1 为什么用 vLLM
裸跑大模型慢、占显存。vLLM 做了三件关键的事:
- PagedAttention:显存按页管理,能塞下更多并发请求。
- Continuous Batching:请求一个接一个批处理,提升吞吐。
- 与 OpenAI API 格式兼容:
/v1/chat/completions,前端代码零改动。
3.2.2 本地起一个 vLLM(示意)
# 拉一个开源模型权重,然后用 vLLM 起 OpenAI 兼容服务
vllm serve Qwen/Qwen2.5-7B-Instruct \
--served-model-name my-qwen \
--port 8000 \
--max-model-len 16384 \
--gpu-memory-utilization 0.85
起好后就能用 OpenAI SDK 调:
from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="EMPTY")
r = client.chat.completions.create(
model="my-qwen",
messages=[{"role": "user", "content": "你好"}],
stream=True
)
3.2.3 显存调优 & 吞吐延迟优化(重点)
--gpu-memory-utilization:给推理预留显存比例,太高会 OOM,太低浪费。--max-model-len:上下文长度上限。太大挤占并发显存,按实际需要设。- PagedAttention + Continuous Batching:默认开着,并发多时吞吐明显提升。
- 量化(想塞进更小显存):模块 13 细讲(AWQ/GPTQ/FP8)。
一句话人话:显存是钱,上下文长=占得多,并发高=吃吞吐,你要在"够用"和"省钱"之间找平衡。
补一段:量化为什么能"塞进更小显存",连续批处理又为什么快
量化的思路很朴素:模型权重默认用 FP16(16 位浮点)存,7B 参数 ≈ 14GB;把权重从 16 位压到 8 位甚至 4 位整数(INT8/INT4),显存直接减半甚至降到 1/4。代价是精度损失一点点,但推理的瓶颈常常卡在"读显存带宽"而不是"算",所以实测往往又快又省。连续批处理(Continuous Batching)快在"把 GPU 算力用满":传统做法是一个请求算完才接下一个,请求之间 GPU 经常空转;连续批处理让多个请求的 token 在同一批里一起算,谁生成了新 token 就随时插进下一批,显卡几乎不歇。两件事合起来,正是 vLLM 能高并发低延迟的核心。想动手看代码(candle 跑 GGUF 量化模型、连续批处理循环)和量化等级对照表,去 Rust + AI 全栈 页补一补。
3.3 模型 API 调用(OpenAI / 通义 / 文心 / DeepSeek 等)
3.3.1 一套通用的"调 API"姿势
import time, random
from openai import OpenAI
client = OpenAI(api_key=os.environ["LLM_API_KEY"], base_url=os.environ.get("LLM_BASE_URL"))
def complete(messages, *, model="deepseek-chat", temperature=0.2, max_tokens=1024):
for attempt in range(3):
try:
return client.chat.completions.create(
model=model, messages=messages,
temperature=temperature, max_tokens=max_tokens,
).choices[0].message.content
except Exception as e:
if attempt == 2:
raise
time.sleep(1.5 ** attempt + random.uniform(0, 0.5)) # 退避重试
要点(面试常考):
- REST/自定义 base_url:各家模型几乎都兼容 OpenAI 格式,换
base_url+api_key就能换供应商。 - temperature:越高越随性、越会发散;审合同这类要确定性,用低 temperature(0~0.2)。
- max_tokens:限制输出长度,防失控、控制成本。
- 超时 & 退避重试:网络抖动在客户现场极常见。
3.4 token、上下文窗口、流式输出(天天踩的坑)
3.4.1 Token 是啥、怎么算钱
- 模型不读"字",读"token"(切分后的最小单元)。中文一般 1~1.5 字 ≈ 1 token。
- 问一句、答一句、还有长 Prompt(系统词+历史)都要算钱。
- 成本公式:成本 ≈ (输入 token + 输出 token) × 单价。所以别把一堆无关历史塞进每次请求。
3.4.2 上下文窗口 = 一次最多能塞多少
- 窗口是上限,你塞进的所有内容(系统词 + 用户问题 + 历史 + RAG 检索片段)的和不能超。
- 人话:窗口是箱子,装太满要么被截断,要么报错,要么效果变差。
- 管理手段:
- 只带最近 N 轮历史(滑动窗口)。
- 压缩长文档(模块 04 RAG 负责检索,而不是全塞进去)。
- 监控 token 用量(模块 08 成本观测)。
3.4.3 流式输出(Streaming)怎么接
大模型一个字一个字吐,体验更好、TTFT 更低。后端把流透传给前端:
from fastapi.responses import StreamingResponse
def stream_chat(messages):
r = client.chat.completions.create(model=..., messages=messages, stream=True)
for chunk in r:
if chunk.choices and chunk.choices[0].delta.content:
yield chunk.choices[0].delta.content
@app.post("/api/chat/stream")
def chat(req):
gen = stream_chat([{"role":"user","content": req.query}])
return StreamingResponse(gen, media_type="text/plain")
千万别忘了:流式也要做超时、重试(幂等)、限流,否则客户一句长话前端会卡死。
3.5 一条能上生产的私有化部署路线
客户机密数据不想出内网的场景,落地红旗如下:
客户内网 GPU 机
└─ vLLM 服务 (/v1/chat/completions)
├─ 模型权重(私有化/开源)
└─ 你的后端服务(鉴权/限流/RAG/Agent)
└─ 客户业务前端
关键决策点(面试/方案常用):
- 模型选型:开源小模型(如 Qwen 系列)还是调通义/文心 API?看数据是否出网、预算、效果要求。
- 推理框架:vLLM 几乎是标配;显存紧张再上量化。
- 环境适配:客户可能是国产服务器/国产 OS(模块 13),提前确认 CUDA/驱动/依赖。
- 并发 & 容量:预估 QPS 和并发,决定几张卡(一张 A100/H 级大概能扛多少并发,要做压测)。
3.6 模块练习
- 本地用 vLLM 起一个开源模型的 OpenAI 兼容服务,用 Python 调通非流式 + 流式两种。
- 给你后端加一个"调模型"封装:温度、超时、指数退避重试、token 用量记录。
- 写一个幂等 + 限流 + 流式的
/api/chat/stream接口,前端用 fetch 读流。 - 做一次简单压测:并发 1/5/10,记录延迟和吞吐,说出"瓶颈在模型还是后端"。
- 画一张"客户机密数据不出内网的私有化部署拓扑图",标出鉴权限流和各层边界。
3.7 本章面试题
- "vLLM 为什么快?" → 答:PagedAttention 提高显存利用率、Continuous Batching 把多个请求合并批处理、并提供 OpenAI 兼容接口。核心是"把显存用得更足、把计算用得更满"。
- "一个 7B 模型跑起来大概要多少显存?" → 答:约 14GB 左右(FP16 权重 ≈ 2×参数量字节),加 KV cache 和量化会更省;具体看量化方式和上下文长度。重点是给面试官展示你的估算逻辑。
- "你怎么控制 token 成本?" → 答:压缩 Prompt、只带必要历史、RAG 只检索最相关片段、限制 max_tokens、用量统计与限流告警、必要时换更小/更便宜的模型。
- "流式输出要注意什么?" → 答:TTFT 低体验好;但要处理超时、断流重连、错误返回;流式同样要限流和幂等,防止并发打爆和重复计费。
- "客户说数据不能出内网,你怎么大概率满足?" → 答:私有化部署:客户内网 GPU 机用 vLLM 起开源/私有模型,后端和 RAG 全在内网,只暴露内网接口并做鉴权限流;评估是否满足效果要求,必要时折中(本地小模型 + 关键场景人工)。
3.8 小结
- 推理 vs 训练:FDE 主要管"推理"——快、稳、便宜。
- vLLM 是私有化部署标配;讲清 PagedAttention 和 batching。
- 调 API:统一 OpenAI 姿势、低 temperature、超时退避重试。
- token/上下文/流式是日常三坑,会管 token 和窗口就是省钱。
- 下一章:怎么把客户文档"喂进"模型——RAG 全链路。
延伸阅读 · 去本站教学页补齐基础
- Rust + AI 全栈——看 GGUF 量化等级怎么选、连续批处理推理服务的完整代码。
- Python AI 数据科学——从 PyTorch 到 FastAPI 推理接口,补齐 Python 侧调模型的地基。
- Spring AI——Java 项目里用一种 ChatClient 姿势接大模型的完整套路。
- 算法与 AI——从 token、上下文窗口到 Transformer 与量化,理解大模型推理的底层原理。
本页由 FDE 培养课程文档生成,完整课程见 FDE 培养 · 课程总览。