ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

LLM入门必读:从预测下一个词到工具调用与本地部署的工程实践

LLM入门必读:从预测下一个词到工具调用与本地部署的工程实践

很多人第一次真正接触 LLM,是在智能对话产品爆火那阵子,把它当成一个"什么都知道的回答机器"。可真到自己接 API、做产品、让模型操作工具的时候才发现,这东西的底层逻辑和我们想象得不太一样——它给出的每一句话都带着概率的味道,同一个问题换个措辞结果可能完全不同,让它调用函数时甚至会凭空捏造参数。这篇《深入学习 LLM》系列的第一篇,不急着让你写 Prompt,也不打算堆热词,而是先把几个最容易被忽略、却决定模型行为的问题讲清楚:LLM 的训练目标到底是什么、模型眼中的文字和人类有什么不同、上下文窗口为什么是有限的、生成时的"随机性"从哪来、本地部署 GGUF 时精度怎么权衡,以及如何避免智能体在工具调用中的各种可靠性事故。适合正在做 AI 应用、想把模型从"黑盒"用成"灰盒"的开发者和爱好者。

1. 先搞明白:LLM 不是一个"知识库",而是一个"接话高手"

1.1 一切的核心:预测下一个词

先做个思想实验。假设手机输入法现在只有一个智能联想——根据你输入的前文,预测下一个字。你打了"床前明月",输入法大概率冒出"光";你打了"今天天气真",它大概率猜到"好"。如果把这种"预测下一个字"的能力放进一个拥有几千亿参数、见过几万亿文本的超级模型里,让它一遍遍预测、预测错就调整参数,最终得到的东西,就是我们说的 LLM(大语言模型)。

这就是为什么很多研究者会把 LLM 调侃成"随机接龙大师"。它的训练目标极其简单:给定一段 token 序列,预测下一个 token 是什么。这来自 Transformer 架构 decoder 分支的自回归设计——把输出重新喂回输入端,一个 token 一个 token 地往后蹦。你在对话里看到的每一句话,本质上都是这个循环跑了几十次甚至几百次的结果。

但问题来了:一个只会"接龙"的模型,凭什么能回答复杂问题、写代码、做推理?关键不在目标,而在语料。预训练阶段,模型吃下去的是全互联网级别的文本——网页、书籍、代码、论文。人类在这些文字里留下的不只是字面信息,还有语法规则、逻辑顺序、知识关联,甚至"提问之后一般会跟着回答"这种对话结构。模型在预测下一个 token 的过程中,被迫把这些规律压缩进参数里。预测的目标是文字,但学到的其实是语言的统计结构和隐含的世界知识。

这里有一个必须纠正的误解:LLM 不是数据库,也不是知识库。它的参数里并没有存一份"百科全书",而是存了"根据目前见过的文本,下一个词最可能是什么"的压缩规则。所以你问它知识,它是在按概率"脑补"一个合理答案,而不是从某个表里精确查询。这也是后面所有幻觉问题的根源——先记住这一点,后面会反复用到。

1.2 "大"在哪里:参数、语料与能力涌现

"大语言模型"的"大"到底指什么?通俗说三件事:参数量大、训练数据量大、算力投入大。7B 参数意味着大约七十亿个权重数字,13B、70B 就是在说这个量级。参数量越大,模型能记住的模式越复杂,但这不是唯一因素——数据量同样关键。后来的 Scaling Laws 系列工作把参数量、数据量、计算量之间的关系做得可以估算:给定参数量,数据量不足时继续增加参数收益会变缓,所以训练实践里"模型规模和语料规模要按比例扩大"基本成了默认常识。

另一个让"大"变得迷人的现象是涌现能力。小模型只会机械续写,但当规模跨过某个临界点之后,模型突然会做数学题、能理解几步推理、甚至能遵循复杂指令。这些能力在小模型上几乎没有痕迹,scale 到一定程度就冒出来,没人能提前完全预测。业内对"涌现是真实的智能飞跃,还是测量方式造成的错觉"还有争论,但有一点是确定的:规模确实会带来行为上的质变。

这一节还想提一个容易忽略的点:模型的"知识"被固定在训练截止时刻。你今天问它最近发生的新闻,它可能一本正经地编一个看起来合理但完全不存在的"事实",因为它的概率分布里根本没有新事件。所以生产环境里在把 LLM 当知识库之前,一定要想清楚——它擅长的是"基于历史语料生成合理文本",不是"实时查证"。

2. Token 与上下文窗口:模型眼中的文字和我们是两回事

2.1 Token 切分:为什么"我爱你"不是三个字

模型并不直接处理字符,它处理的是一种叫 token 的最小单位。token 可以是一个词、半个词,甚至一个汉字或几个汉字的组合。把原始文本切成 token 编号的过程叫 tokenization。

最常见的切分算法是 BPE(Byte Pair Encoding,字节对编码)。它先把文本拆成单字节,然后反复把出现频率最高的相邻对合并成一个新 token,直到词表达到指定大小。拿英文举例,"unbelievable" 可能会被切成 "un"、"belie"、"able" 这样几个更小的 token,而不是整个单词——这样模型既能处理没见过的生词,又不用把每个词都单独存一份。

中文的情况有点特殊。因为常用汉字本身就是独立的语义单元,很多中文 tokenizer 会把单个汉字或双字词作为 token 单位。以流行的 GPT 系列 tokenizer 为例,一个常见汉字通常是 1 个 token,一个成语可能被切成两三个 token,英文一个常见单词通常也是 1 个 token。这带来的直接后果是:同样一段话,中英文的 token 消耗在 API 计费上可能相差不少。建议你自己跑一次 tokenizer 看看,很多反直觉的结论都会出来。

为了看得直观,这里是几个 token 切分的参考例子(不同模型词表略不同):

输入文本切分结果示例大致 token 数
Hello worldHello / world2
你好,世界你 / 好 / , / 世界4
人工智能正在改变世界人工智能 / 正在 / 改变 / 世界4
supercalifragilisticsuper / cali / frag / ilistic3~5

理解 token 对工程有着实际意义:第一,上下文窗口预算、计费、KV Cache 占用都按 token 算;第二,长文本截断策略如果按字符切,容易切坏语义边界;第三,有些模型对 token 序列格式很敏感,中文里多加一个空格都可能改变行为。

2.2 上下文窗口:为什么模型"记性"有限

模型每次生成前能"看到"的输入长度,叫上下文窗口。现在的模型动辄支持 128K、200K token,听起来很长,但实际并不是"给它多少它就能记住多少"。

原因是模型自注意力机制的计算量通常随序列长度平方增长。窗口越长,中间层的注意力矩阵越大,显存占用和推理延迟都受不了。即便工程上做了 Flash Attention、KV Cache、稀疏注意力等优化,超长上下文仍是一个成本和效果都要权衡的事。

更让开发者头疼的是"长上下文失效"现象:你给它塞了一篇 10 万 token 的文档,模型可能只记住开头和结尾,漏掉中间的关键信息。心理学里有点像首因效应和近因效应——模型在处理超长文本时,注意力会被开头和结尾带偏。所以做 RAG(检索增强)而不是把所有资料一股脑塞进 prompt,是有充分理由的:与其给一个"记不住的记忆宫殿",不如把最关键的内容精确地放到模型视野内。

3. 训练流水线:从语料到"会听话的助手"要经历什么

3.1 预训练:烧钱学语言的阶段

LLM 的"学历"分阶段,第一阶段是预训练。预训练做的事就是我们开头说的"接龙游戏",只不过语料庞大到可怕:几十万亿 token 的网页、书籍、代码、论文混合在一起,经过清洗、去重、过滤之后,分批喂给模型。

训练时,模型对每个位置输出下一个 token 的概率分布,用交叉熵损失和正确答案做对比,算出梯度,再用反向传播更新参数。整个过程的计算量以 exaFLOPs 计,对应的就是电力、GPU、时间和人力成本。这也是为什么预训练大模型越来越集中在少数机构手里——不是技术壁垒有多高,而是算力和资本的门槛。

预训练结束的模型是什么状态?它能流畅续写任何文本,语法几乎完美,但它不懂"对话"。你给它一句"今天天气怎么样",它最大的概率是接着写"怎么样,你那边呢?我今天……",而不是回答"今天晴转多云"。真正让它"会回答问题"的,是后面的阶段。

这里需要补一个重要概念:Scaling Laws。简单说,当模型参数量、数据量、计算量按某个比例共同增长时,loss 会以可预测的方式下降。这带来两个实务结论:一是训练大模型之前就可以根据预算推算效果;二是当模型能力不达标时,先加数据往往比狂加参数更划算——这个经验现在基本成了业界的默认操作。

3.2 微调与对齐:把"天才话痨"变成"靠谱助手"

预训练之后,模型通常在大量"指令-回答"对上进行监督微调(SFT)。这一步叫指令微调,目的是让模型学会按人类的格式要求作答。数据质量在这里至关重要——哪怕只有几千几万条高质量指令数据,效果都经常好过灌进去百万条杂乱样本。现在很多公司做垂直模型,本质上也是通用底座上的 SFT 加继续预训练。

之后是对齐阶段。经典的 RLHF(基于人类反馈的强化学习)流程是:先让人类对回答排序打分,训练一个奖励模型来模拟人类偏好,再用强化学习让策略模型学着获取更高奖励。后来出现的 DPO 方法更省事,不再需要单独的奖励模型,直接在偏好数据上训练,效果却相当接近。这一整步的意义,是让模型学会"什么话该说、什么话不该说、怎么拒绝、怎么表达不确定性"。

这个阶段有一个很实际的工程经验:如果你手里有大量对话记录(比如客服聊天记录),别直接拿去 SFT。原始对话里有太多噪声、错误信息、角色混乱的文本,直接喂给模型,会把"不该学的话"也学进去。我见过不止一个团队拿聊天记录精调 LLM,结果模型学会了在开头加"亲,很高兴为您服务",还学会了把未经核实的信息当事实。正确的做法是先清洗、去重、改写,把"用户-助手"角色对齐,再删掉噪音,最终控制在几千到几万条高质量数据。

4. 生成与幻觉:同样是概率,为什么有时靠谱有时胡说

4.1 采样参数如何影响每一次输出

即使训练完,模型在推理时也不是简单地"取概率最大的 token"。为了让回答不机械,通常引入随机采样。你可以把它理解成:模型对每个可能的 token 给出一个概率,然后按概率抽样。这里有几个核心参数:

  • temperature(温度):控制概率分布的"尖锐程度"。温度越低,高概率 token 更容易被选中,回答更确定;温度越高,低概率 token 也有机会冒出来,回答更有发散性。
  • top_p:只在累计概率达到 p 的 token 集合里抽样,超出部分砍掉。这也叫核采样,比 temperature 更贴近实际生成效果。
  • top_k:只保留概率最高的 k 个 token 参与采样,太冷门的候选直接排除。

实践优先级大概是:先调 temperature,再调 top_p。写代码、做 JSON 输出、工具调用,温度调到 0 或很低,保证稳定;写文案、头脑风暴,温度调到 0.7~1.0,让模型敢说"奇怪的话"。我见过很多线上事故都是因为默认温度太高,模型在 function calling 时随意发挥输出非法参数——这不是模型"傻",是采样策略没有对齐到任务约束。

提示:生产环境里做 function calling,temperature 建议直接设 0 或很低,千万别用默认值。我踩过一次线上事故,就是模型在默认温度下自由发挥,把一个价格字段传成了带引号的字符串,下游校验直接炸了。

4.2 幻觉、长上下文失效与"LLM as Judge"的坑

幻觉为什么难以根除?因为预训练的本质是学习"下一个 token 的概率分布",而不是建立"事实数据库"。模型会优先给出"听起来最顺"的回答,而不是"经过验证的事实"。再加上训练数据里本身就存在错误、矛盾、过时信息,幻觉是必然的副作用。目前的缓解手段——搜索引擎增强、RAG、外部工具验证——本质上都是"在模型外面加护栏",而不是让模型真的学会区分真伪。

"LLM as Judge"这个概念,指的是用一个 LLM 给另一个 LLM 的回答打分。这样做省了人工评审成本,但隐患很大:LLM judge 倾向于给更长、更花哨的答案打高分;它对排序结果有系统偏好,比如位置靠前的答案会被高估;如果两个模型能力接近,judge 的判断稳定性会很差。所以我的经验是:可以用 LLM 做粗筛,但核心评估指标必须保留自动化校验和人工抽样,千万别只靠"AI 评 AI"。

长上下文失效同样值得重视。即便窗口支持 128K,当你把答案藏在长长的文档中间时,模型可能完全无视。很多 RAG 产品召回了一堆 chunk,按顺序全塞进 prompt,结果核心答案反而被淹没。正确做法是:把高置信度的片段放在上下文开头或结尾,或者用重排再压缩到更小的窗口。别高估模型的"长情",它只是个接话高手,不是真正的读者。

5. 从 API 到本地部署:量化、GGUF 与生产环境的可靠性

5.1 为什么本地跑:GGUF 与量化精度权衡

很多工程师自从用了云端 API 之后,就不再碰本地模型了。但凡是涉及隐私数据、离线环境、长期成本控制的场景,本地部署仍然是绕不开的选择。本地部署绕不开的一个名词是 GGUF。

先说背景。Llama.cpp 项目为了在消费级硬件上跑大模型,设计了一种叫 GGUF 的模型格式——它把模型权重、词表、超参数打包进一个文件,同时内置量化支持。量化听起来复杂,本质就是"用更少的 bit 存储神经网络权重"。原来的 fp16 权重每个数占 2 字节,量化成 4bit 后只占 0.5 字节,模型文件直接缩小到原来的四分之一左右,运行内存占用也随之降低,代价是精度损失。

常见的量化级别我整理了一下:

量化类型含义大致效果
Q8_08bit 量化精度损失极小,文件较大
Q5_K_M5bit 混合量化精度/体积平衡较好
Q4_K_M4bit 混合量化日常使用首选,体积小
Q2_K2bit 量化文件最小,但质量下降明显

选量化级别没有标准答案,要看硬件和任务:如果跑 7B 模型做代码生成,Q8 或 Q5 值得考虑;如果内存只有 8GB,Q4 是现实选择;跑 70B 级别模型还想不卡,Q4/Q3 几乎是唯一方案,而且长上下文会更吃力。移动端同样有生态,不少人用开源加载器在手机上跑 1B~8B 模型,老设备(比如 Android 8 系统)能不能跑主要看芯片和内存,系统版本只是门槛之一。

GGUF 的实际使用通常配 Ollama 或 llama.cpp 这类工具。启动一个本地模型并保持稳定输出,最关键的是看两点:内存带宽和可用内存。内存带宽决定了每秒能生成多少 token,容量决定最大能装下多大的模型。所以本地部署前先看自己机器的"碗有多大",再决定吃哪碗饭,比盲目下载最大模型明智得多。

5.2 工具调用报错与智能体容错的工程实践

本地部署的另一大坑是工具调用。现在主流模型支持在回答时输出结构化调用请求,比如"调用 search_web 接口,参数 keyword=..."。这对智能体尤其关键——你让模型决定下一步用哪个工具、传什么参数,它不是在查文档,而是在"猜最可能的调用方式",所以报错很常见。

我遇到最典型的报错长这样:"llm request failed: provider rejected the request schema or tool payload"。字面意思是"模型服务商拒绝了请求模式或工具数据"。绝大多数情况不是模型坏了,而是工具定义 schema 和模型能力不匹配。常见诱因包括:

  • 工具参数用了普通 JSON 无法表达的格式,比如undefined、NaN、特殊嵌套。
  • 参数类型声明和实际值对不上,模型输出字符串但 schema 声明 number。
  • 工具描述写得太模糊,模型不知道什么时候该调、该传什么。
  • 工具列表太长,超出模型对 function calling 的理解范围,它输出了 schema 里不存在的参数名。

处理思路是分层防御:第一层,校验 JSON 结构,解析失败就重试并明确告诉模型错在哪;第二层,运行时校验参数类型,不匹配就返回修正提示;第三层,设置最大重试次数,超过就降级为"不调用工具直接回答"或交给兜底流程。这套组合拳在智能体工程里特别重要——说到底,不要在模型"犯错"时指望它自己变聪明,而是用外部约束和回退机制兜住它的随机性。

另一个容易被忽略的是安全。把外部内容喂给智能体之前,要意识到恶意注入风险——有红队研究表明,攻击者可以污染记忆库或知识库,让智能体根据预设触发条件输出有害行为或泄露信息。这不是耸人听闻,而是真实工程里必须防的东西:对来源不可信的知识块做隔离和权限分层,对模型生成的工具调用加白名单,对敏感操作加人工审批,这些都应该出现在你的可靠性设计里。

6. 学习路线与实用工具:入门 LLM 别走弯路

6.1 "论文 + 代码 + 复现"三件套

如果一个新手让我推荐最快的学习节奏,我会说:先别再刷短视频教程了,把下面三件事套着做。

第一,把官方 API 跑通。选任何一个主流模型服务商,调通聊天补全接口,打印出完整请求和响应,观察 temperature 和 system prompt 对输出的影响。第二,本地装一个 Ollama,拉一个 7B 模型下来,写代码把 tokenizer 切分结果打印出来,再测一测不同上下文长度下的行为变化。这两步能让你对"模型看到的是什么"有真实的体感。

第三,再回到论文。我的建议阅读顺序是:先读《Attention Is All You Need》中的核心注意力公式,然后读一篇讲缩放定律的综述,接着读 LLaMA 及相关模型论文,最后针对你关心的方向(agent、评估、检索增强)找几篇引用量高的读。读论文不用硬抠每一个公式,关键是搞懂"为了解决什么问题、用了什么思路、限制条件是什么"。

开源社区里还有一条捷径:参与复现型项目。比如自己用小规模数据从零训练一个几十层的小 Transformer,或者在开源社区跑通一个微调脚本。这种动手经验远比看一百个视频来得扎实。

6.2 框架与工具:LLM Studio、Ollama 与主流编排框架怎么选

工具层面,我的建议是分类使用:

  • 本地跑模型:Ollama 是我目前首推,一条命令装模型、起服务;LLM Studio 这类带图形界面的工具适合不想碰命令行、想快速对比多个模型效果的人,可以直观看到量化级别和推理参数变化。严格说,LLM Studio 更多是桌面实验工具,生产环境我一般还是会回到 API 或 llama.cpp/vLLM 这一套。
  • 业务编排:LangChain、LlamaIndex 这类框架能帮你快速把 RAG、工具调用、Agent 循环搭起来。但我的意见很明确:刚开始别急着上框架,先用裸 API 把一条链路写明白,再回来用它,这样你对框架藏起来的东西有控制力。框架只是脚手架,不是思维替代品。
  • 生产部署:vLLM 是高并发推理服务的常客,支持连续批处理和 PagedAttention,吞吐量明显优于朴素的 API 包装;TensorRT-LLM 偏 GPU 优化,适合固定形状推理。
  • 评估与测试:现在有人用 LLM 自动生成单元测试用例,概念很好,但生成出来的测试要人工审查,别盲目全量采纳。评估工具可以理解为一个"评分系统",但对最终产出还是要保留人工兜底。

优质资料入口,我建议盯住官方文档和论文仓库,很多名字里带 wiki 或 awesome 的汇总项目能帮你省掉大量搜索时间。但要注意甄别时效性——LLM 这个领域半年就是一代,只看最新、最贴近一线的资料才能少走弯路。

最后分享一点个人体会。学 LLM 最大的坑不是"不懂原理",而是"好像都懂了,一动手全是意外"。我自己重新走一遍的话,会先从本地 Ollama 拉一个 7B 模型,写脚本打印 tokenizer 切分结果,再故意用"系统提示 + 工具调用错误 + 重试修正"的组合调几个场景,把这些坑全部踩一遍。没有亲手看过模型怎么切词、怎么在温度变化时改输出,所有的深度教程都只是听了个热闹。

这个系列的第一篇先停在这里。下一篇我打算沿着注意力机制往下拆,把 QKV、位置编码、KV Cache 这些概念结合实际推理过程彻底讲清楚,到时候我们继续。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进