大模型基础
这一篇的目标很具体:能算清一次调用多少钱、能选对模型、能解释为什么它有时候胡说。Transformer 的公式不用背,但「为什么长上下文贵」必须能讲明白。
1. LLM 到底在做什么
大模型本质是一个概率函数:给定前面的 token 序列,输出下一个 token 的概率分布。生成就是不断「采样一个词 → 接到序列后面 → 再预测」的循环。
输入: "今天天气真"
↓ 模型
概率: { "好": 0.62, "不错": 0.15, "热": 0.08, ... }
↓ 采样
输出: "好"
↓ 拼回输入
"今天天气真好" → 继续预测下一个输入: "今天天气真"
↓ 模型
概率: { "好": 0.62, "不错": 0.15, "热": 0.08, ... }
↓ 采样
输出: "好"
↓ 拼回输入
"今天天气真好" → 继续预测下一个这解释了三件事:
- 为什么有随机性:它是采样,不是查表;
temperature调的就是采样策略。 - 为什么会编:它优化的是「像不像人话」,不是「对不对」。
- 为什么慢:每个 token 都要过一次模型,输出 500 token 就是 500 次前向(虽然有 KV Cache 复用)。
2. Token 与上下文窗口
- 一个汉字 ≈ 1~2 token,一个英文单词 ≈ 1~1.3 token;
- 计费按 token,且输入和输出价格不同(输出通常贵 2~4 倍);
- 上下文窗口是「输入 + 输出」的总和,输出也占额度。
为什么长上下文贵:注意力机制要对「每个 token 和之前所有 token」算相关性,计算量随长度平方增长($O(n^2)$)。所以 128k 上下文的成本不是一个 16k 请求的 8 倍,而是高得多,延迟也明显变长。
工程含义:别把整个知识库塞进去,只放检索出来最相关的几段(见 03 RAG)。
3. Transformer 与注意力(够用版)
自注意力回答一个问题:当前这个词,应该多重关注前文的哪些词?
Query(我在找什么) × Key(每个词的标签) → 相关性分数
↓ softmax 归一化
对 Value(每个词的内容)加权求和Query(我在找什么) × Key(每个词的标签) → 相关性分数
↓ softmax 归一化
对 Value(每个词的内容)加权求和举例:「银行」这个词在「河边的银行」和「去银行取钱」里,注意力的落点完全不同 —— 这就是上下文消歧的原理。
必须知道的三个工程结论:
| 结论 | 原因 |
|---|---|
| 长上下文成本平方增长 | 注意力矩阵 n×n |
| KV Cache 能大幅加速 | 已生成部分的 K/V 缓存复用,避免重算 |
| 「Lost in the middle」 | 放在上下文中间的信息容易被忽略,头尾更容易被利用 |
4. 采样参数:怎么让它稳定 / 发散
| 参数 | 作用 | 建议 |
|---|---|---|
temperature | 温度,越低越确定 | 事实问答 0~0.3;创意 0.7~1 |
top_p(核采样) | 只从累计概率前 p 的词里选 | 一般 0.9~0.95,和 temperature 只调一个 |
top_k | 只从概率最高的 k 个词里选 | 少用,top_p 更常用 |
repetition_penalty | 惩罚重复 | 1.0~1.2,太高会不通顺 |
max_tokens | 输出上限 | 必设,防跑飞烧钱 |
stop | 遇到指定串就停 | 结构化输出时很有用 |
seed | 固定随机种子 | 要可复现(测试/评测)时用 |
经验:要稳定就 temperature=0 + 固定 seed,但注意很多厂商在 0 也不是完全确定的(并行计算导致浮点误差)。
5. 幻觉:成因与三层缓解
| 层 | 手段 |
|---|---|
| 输入层 | 提供资料(RAG)、限定「资料没有就说不知道」、Few-shot 给正确范式 |
| 生成层 | 降 temperature、要求引用出处、结构化输出(先给结论再给依据) |
| 输出层 | 事后校验(规则/小模型/交叉验证)、关键数字走工具计算、人工兜底 |
认知:幻觉是「生成的本质」决定的,不可能消除。工程上追求的是「幻觉可发现、可拦截」,不是「没有幻觉」。
6. 模型选型:四个维度
| 维度 | 要问什么 |
|---|---|
| 能力 | 任务复杂度(推理/代码/长文/多语言/多模态)够不够 |
| 价格 | 输入/输出单价 × 预估 token 量 = 每次调用成本 |
| 延迟 | 首 token 延迟(流式体验)+ 输出速度(tokens/s) |
| 合规 | 数据能不能出境、能不能用于训练、要不要私有化 |
常见组合策略:
- 主力 + 兜底:主力模型做业务,备用模型(不同厂商)防故障;
- 大小搭配:简单意图识别/改写用小模型,复杂推理用大模型(见 07 工程化 的模型路由);
- 国内外双活:合规与稳定性兼顾。
别只看榜单。用自己的 20 条真实 badcase 跑一遍,比任何 benchmark 都准。
7. 部署:API 还是自己跑
| 方式 | 适合 | 代价 |
|---|---|---|
| 云 API | 绝大多数业务,快速上线 | 按 token 付费、数据出域 |
| 私有化部署开源模型 | 数据不能出内网、量大到划算 | 机器成本 + 运维 + 调优 |
7.1 推理引擎
| 引擎 | 定位 |
|---|---|
| vLLM | 生产首选,PagedAttention + 连续批处理,OpenAI 兼容接口 |
| Ollama | 本地开发最省事,GGUF 格式,一行命令跑起来 |
| SGLang / TensorRT-LLM | 极致性能,调优成本高 |
两个关键优化:
- PagedAttention:像操作系统分页一样管理 KV Cache,显存碎片大幅减少,吞吐提升数倍。
- 连续批处理(Continuous Batching):一个请求生成完立刻腾出位置给新请求,而不是等整批结束。
7.2 量化
| 方案 | 位宽 | 场景 |
|---|---|---|
| GPTQ / AWQ | 4bit | GPU 推理,精度损失小 |
| GGUF | 2~8bit | CPU / 混合,Ollama 用这个 |
| FP8 | 8bit | 新卡(H100 等)原生支持 |
7.3 显存怎么算(面试常问)
显存 ≈ 权重 + KV Cache + 激活值
权重 = 参数量 × 每参数字节数(fp16=2B,int8=1B,int4=0.5B)
KV Cache ≈ 2 × 层数 × 头数 × head_dim × 序列长度 × batch × 字节数显存 ≈ 权重 + KV Cache + 激活值
权重 = 参数量 × 每参数字节数(fp16=2B,int8=1B,int4=0.5B)
KV Cache ≈ 2 × 层数 × 头数 × head_dim × 序列长度 × batch × 字节数粗算经验:7B 模型 fp16 约 14GB 权重 + 余量 ≈ 16GB 显存;70B fp16 约 140GB,必须多卡或量化。
8. 成本与延迟模型
一次调用的钱由三部分组成:
成本 = 输入token × 输入单价 + 输出token × 输出单价 (+ 缓存命中折扣)成本 = 输入token × 输入单价 + 输出token × 输出单价 (+ 缓存命中折扣)延迟分两段:
- 首 token 延迟(TTFT):主要是 prefill(把整段输入算一遍),输入越长越慢;
- 后续 token 速度(TPOT):decode 阶段,通常 20~80 tokens/s,输出越长总时长越久。
优化方向:砍输入(RAG 只放 Top-K)、限输出(max_tokens、要求简洁)、缓存(相同前缀的 prompt cache)。
9. 评测:别只看榜单
| 类型 | 做法 | 局限 |
|---|---|---|
| 公开榜(MMLU、C-Eval 等) | 看个大概 | 和你的任务相关性低 |
| 自建评测集 | 20~200 条真实问题 + 标准答案/评分规则 | 最有效,但要持续维护 |
| LLM-as-judge | 用强模型打分 | 有偏好偏差(偏爱长答案、偏爱同族模型) |
| 人工抽检 | 定期抽样 | 贵,但必须有 |
落地顺序:先有 20 条 badcase 组成的最小评测集,再谈优化。没有评测集的「调优」都是玄学。
10. 速查表
| 问题 | 一句话 |
|---|---|
| LLM 本质 | 自回归预测下一个 token 的概率分布,采样生成 |
| 为什么长上下文贵 | 注意力 O(n²),且输入按 token 计费 |
| temperature | 控制采样随机性,事实任务用 0~0.3 |
| top_p 与 temperature | 都是采样参数,一般只调一个 |
| KV Cache | 缓存已算的 K/V,decode 阶段不必重算前文 |
| 幻觉能消除吗 | 不能,只能靠 RAG + 低温度 + 引用 + 事后校验缓解 |
| 模型怎么选 | 能力/价格/延迟/合规四维,用自己的 badcase 测 |
| 显存怎么估 | 参数量 × 字节数 + KV Cache,7B fp16 ≈ 16GB |
| vLLM 强在哪 | PagedAttention + 连续批处理,吞吐数倍提升 |
| 首 token 为什么慢 | prefill 要把整段输入算一遍 |
Cao Note