对于Swift开发者来说,大语言模型 (LLM) 技术可能一开始会显得有些复杂,特别是当大多数教程直接深入到神经网络内部和数据科学术语时。但现在,像 MLX-Swift 这样的 Swift 库让我们可以免费地在本地 Mac 或 iOS 设备上运行最前沿的 LLM,理解这些模型变得前所未有的重要。本文将以 Swift 开发者的视角,用清晰、实用的方式解释 LLM 的核心概念,无需深奥的数学或 AI 知识,帮助你快速入门并掌握 LLM 技术。

1. LLM 的核心:预测下一个 Token

Token 是理解 LLM 的关键概念。简单来说,LLM 的核心任务就是预测下一个 Token。Token 不一定是完整的单词,它可以是单词的一部分、标点符号甚至是空白。LLM 会不断地观察到目前为止的文本(prompt),然后选择最有可能的下一个 Token,将其添加到 prompt 中,并重复这个过程,直到生成一个 “end-of-sequence (EOS)” Token,标志着文本生成结束。

举个例子,如果我们给 LLM 一个 prompt “The quick brown fox”,LLM 可能会预测下一个 Token 是 ” jumps”。然后,prompt 变成 “The quick brown fox jumps”,LLM 会继续预测下一个 Token,直到生成完整的句子。这种逐步预测的方式,是 LLM 生成文本的基础。不同的 Tokenizer 会将原始文本切分成不同的 Token 序列,因此理解 Tokenizer 的工作原理对理解 LLM 的行为至关重要。

2. LLM 的组成部分:推理引擎、Tokenizer 和模型权重

一个 LLM 系统可以被认为是由几个只读文件组成:推理引擎Tokenizer模型权重

  • 推理引擎:一个运行模型的程序,可以非常小巧,甚至可以用简单的代码从头开始编写,不需要任何外部库。
  • Tokenizer (tokenizer.json):负责将文本分解成 Token,并将每个 Token 转换为唯一的 ID。
  • 模型权重 (DeepSeek-R1–0528–3bit.safetensors):包含了模型学习到的所有知识,是 LLM 的核心。模型权重通常体积庞大,需要占用大量的存储空间。

可以把 Tokenizer 比作一本字典,将文本转换成机器可以理解的数字表示;模型权重则像是 LLM 的大脑,包含了模型学习到的所有信息。而推理引擎,则是运行这个“大脑”的程序。

3. 文本分解:Tokenizer 的作用

Tokenizer 的作用是将文本分解成 Token,并将每个 Token 转换为唯一的 ID。这个过程类似于 ASCII 或 Unicode,但是 Tokenizer 处理的是子词、标点符号和空格。

例如,Tokenizer 可能会将 “user” 分解成一个 Token,并为其分配一个 ID,比如 1972。这个 ID 对应于词汇表中的一个条目。一些 Tokenizer 还会使用特殊的 Unicode 字符(如 U+2581)来标记 Token 只能在空格后使用。

在 Swift 中,我们可以将 Tokenizer 理解为一个查找表:

let word = vocab[1972] // "user"

其中 vocab 是一个数组,包含了所有可能的 Token。通过 Token ID,我们可以快速地找到对应的文本。不同的 LLM 使用的 Tokenizer 可能不同,例如 OpenAI 的 GPT 系列模型使用 BPE (Byte Pair Encoding) Tokenizer,而 Google 的 BERT 模型使用 WordPiece Tokenizer。选择合适的 Tokenizer 对于 LLM 的性能至关重要。

4.赋予 Token 意义:Embeddings 的妙用

每个 Token ID 都会被映射到一个向量,这个向量被称为 Embedding。可以将 Embedding 想象成 Token 在一个高维空间中的 “GPS 坐标”,相似含义的 Token 在这个空间中的距离会更接近。

在训练过程中,LLM 会学习到每个 Token 的最佳 Embedding,并将它们存储在一个大的 Embedding 矩阵中。

在 Swift 中,我们可以这样获取 Token 的 Embedding:

let userEmbedding = embeddingMatrix[1792] // E.g. [12.46342, 4542.234, …]

其中 embeddingMatrix 是一个 [[Float]],每一行对应一个 Token ID 的 Embedding。 Embedding 的维度通常是几百甚至几千维,例如,GPT-3 使用的 Embedding 维度是 12288 维。 Embedding 的质量直接影响 LLM 的性能,好的 Embedding 可以更好地捕捉 Token 之间的语义关系。

5. LLM 的大脑:Transformer 的工作原理

Transformer 是 LLM 的核心组件,也被称为“黑盒”。它接收 Embedding 序列(即 prompt 和模型已生成的文本)和模型权重,输出一个新的数组,被称为 Logits。Logits 包含了每个可能的下一个 Token 的原始分数。

Transformer 的具体工作原理涉及到复杂的数学运算,包括自注意力机制 (Self-Attention) 和前馈神经网络 (Feed Forward Network)。自注意力机制可以让模型关注到输入序列中不同 Token 之间的关系,从而更好地理解文本的含义。

6. 分数转化为概率:Softmax 的应用

Logits 很难直接解释,因此我们需要使用 Softmax 函数将它们转换为概率。Softmax 函数将 Logits 数组转换为概率分布,其中每个值都在 0 和 1 之间,且所有值之和为 1。

在 Swift 中,我们可以这样计算 Token 的概率:

let probabilityForUser = probabilityVector[1792] // E.g. 0.12453

其中 probabilityVector 是 Softmax 函数的输出,包含了每个 Token 的概率。Softmax 的输出可以用来选择最有可能的下一个 Token。

如果你用过 iOS 键盘上的自动完成或预测文本功能,你就会发现 Softmax 的应用。系统会计算每个可能下一个 Token 的概率,然后显示概率最高的几个选项。

let topThreeIndices = probabilityVector
                         .enumerated()
                         .sorted(by: { $0.element > $1.element })
                         .prefix(3)
                         .map { $0.offset }
let topThreeTokens = topThreeIndices.map { vocab[$0] }
print(topThreeTokens) // E.g. ["user", "person", "client"]

7. 增加随机性:选择下一个 Token

到目前为止,LLM 的流程是完全确定性的:输入相同的 prompt,输出的结果总是相同的。但是,为了让 LLM 的对话感觉更自然,我们需要在选择下一个 Token 的过程中引入一些 随机性

我们可以通过 Sampler 来调整概率值,从而实现随机性。常见的 Sampler 策略包括:

  • Temperature:控制模型的 “创造性”。值越高,随机性越高。
  • Top-K:只保留 K 个最高概率的 Token,忽略其余的 Token。
  • Top-P:保留概率之和至少为 P 的最小 Token 集合。

通常的顺序是:先使用 Temperature 调整概率,然后应用 Top-K 或 Top-P,最后再次标准化概率值。如果想要保证完全可预测的结果(没有随机性),可以将 Temperature 设置为 0 (也称为 “greedy” 或 “argmax” 模式)。另一种方式是将 Temperature 设置为 1,并将 Top-K 设置为 1,这也意味着 “总是选择概率最高的 Token”。记住:使用 Temperature > 1 或 Top-K > 1 会引入随机性。

8. 循环迭代:生成完整文本

一旦选择了下一个 Token,它会被添加到 prompt 中,然后重复整个过程(Embedding -> Transformer -> Logits -> 概率 -> Sampler -> 下一个 Token),直到模型输出 end-of-sequence (EOS) Token。这样,我们就得到了生成的完整文本!

例如,假设我们让 LLM 生成一个关于 Swift 的段落,LLM 可能会按照以下步骤生成文本:

  1. Prompt: “Swift is a powerful”
  2. Next Token: ” programming” (根据概率选择)
  3. Prompt: “Swift is a powerful programming”
  4. Next Token: ” language” (根据概率选择)
  5. Prompt: “Swift is a powerful programming language”
  6. Next Token: “.” (根据概率选择)
  7. Prompt: “Swift is a powerful programming language.”
  8. Next Token: EOS (end-of-sequence token)

最终,LLM 生成的文本为 “Swift is a powerful programming language.”

9. 实践体验:MLX-Swift 驱动的 LLM

现在,你可以亲自体验 MLX-Swift 驱动的 LLM。我的应用 Pico AI Server 是 Mac App Store 上最受欢迎的 LLM 和 VLM 服务器。它完全用 Swift 编写,并构建在 Apple 的 MLX-Swift 框架之上。使用 Pico AI Server,你可以在自己的 Mac 上运行 DeepSeek、Llama、Gemma 等最先进的模型。你甚至可以通过局域网与同事、家人或室友共享这些模型,让每个人都可以在自己的设备上利用强大的 AI。该应用是免费下载的,如果你觉得它有用,请在 App Store 上给它评分或评价!

通过 Pico AI Server,你可以直接体验 LLM 的强大功能,例如:

  • 文本生成:生成各种类型的文本,例如文章、诗歌、代码等。
  • 文本摘要:从长篇文章中提取关键信息。
  • 问题回答:根据文本内容回答问题。
  • 机器翻译:将文本从一种语言翻译成另一种语言。

Pico AI Server 为 Swift 开发者提供了一个便捷的平台,可以快速地将 LLM 集成到自己的应用中。

总结:

本文以 Swift 开发者的视角,深入浅出地介绍了 LLM 的核心概念,包括 TokenTokenizerEmbeddingsTransformerLogitsSoftmaxSampler。希望通过本文,你能对 LLM 有更深入的理解,并能够将 LLM 技术应用到自己的 Swift 项目中。理解这些核心概念,结合 MLX-Swift 框架和 Pico AI Server,你就可以在 Swift 应用中构建强大的 LLM 功能。掌握了这些知识,你就能更好地利用 LLM 技术,为你的 Swift 应用增加更多可能性。