前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

一、大模型开发基础

所有语言模型的背后,都有一套将文字变成数字的魔法系统,这就是 Embedding(嵌入)

1、通用人工智能的前夜

Embedding 是通往 AGI 的“桥梁”

什么是“通用人工智能”(AGI = Artificial General Intelligence = 人工通用智能)?

AGI 是指:像人一样思考、学习、适应各种任务的智能体

目前我们离 AGI 还很远,但已经迈出了重要一步—— 从“规则驱动”到“数据驱动”再到“表示驱动”

阶段 方法 局限
1. 规则系统 人工写规则(如“如果下雨,就带伞”) 太死板,无法处理新情况
2. 机器学习 用数据训练模型(如识别猫) 只能做特定任务
3. 表示学习(Embedding) 把知识“编码”成向量,支持泛化 支持多任务、跨领域

2、三个世界”与“图灵测试”

1)「三个世界」理解现实的哲学框架

三个世界相互关联,但又各自独立。人类的特殊之处在于,我们能够将世界一的体验(世界二),转化为世界三的知识,并利用世界三的知识去改造世界一。

  • 世界一 是“有形的物质”,是基础。
  • 世界二 是“无形的体验”,是主观感受。
  • 世界三 是“可传递的知识”,是人类集体智慧的结晶。

a、物理世界(客观世界)

  • 是什么? 由所有物理客体和事件组成的世界。
  • 包含什么? 物质、能量、一切有机和无机物质。简单说,就是我们能用感官直接接触、测量和观察到的客观实在
  • 例子: 山川河流、你的身体、手机、电脑、光、声音、温度等。

b:心理世界(主观世界)

  • 是什么?心灵主体及其感知事件组成的世界。
  • 包含什么? 所有的心理状态和过程,如感觉、知觉、意识、情绪、欲望、痛苦、快乐、信念、意图等。这是个体的主观体验
  • 例子: 看到红色时产生的“红”的感觉、失恋时的心痛、对未来的期待、正在思考问题的意识流。

c、知识世界(客观知识世界)

  • 是什么?客观知识组成的世界。
  • 包含什么? 思想的内容,这些思想可以被物化(具体化)为各种形式的人造产品和文化产品。它超越了个人的心理状态,成为独立于个体存在的客观存在
  • 例子:
    • 语言文字:一本书、一篇论文、一段代码。
    • 艺术作品:一幅画、一首歌、一部电影。
    • 技术产品:智能手机、计算机、汽车的设计图。
    • 抽象概念:科学理论(如相对论)、数学公式、法律条文、社会制度、哲学问题、猜想、反驳等。

d、为什么这对理解 AI 很重要?

AI的强大在于其处理世界三的能力,但其局限也根植于它无法真正进入世界二和世界一的深度

  • 当前的AI(如ChatGPT)主要在世界三中活动:它处理、分析、生成和重组已有的知识和信息(文本、数据)。
  • 它能“感知”世界一的信息(通过传感器),但缺乏对世界一的直接、真实的物理体验和交互能力。
  • 它能“模仿”世界二的表达(如共情话语),但无法真正拥有世界二的主观体验(如真正的痛苦或喜悦)。

2)图灵测试(Turing Test)

1950年,英国计算机科学家艾伦·图灵Alan Turing)发表了一篇具有划时代意义的论文《计算机器与智能》(Computing Machinery and Intelligence),首次系统地探讨了机器是否能思考这一深刻问题。

a、含义

核心规则:如果一台机器能够通过电传设备(如键盘和屏幕)与人类进行对话,而人类无法仅凭对话内容判断出对方是机器还是人,那么这台机器就可以被认为具有“智能”或“会思考”。

简单理解:可以把它想象成一场“角色扮演”游戏:机器扮演人类,人类裁判需要通过聊天来识别谁是真人、谁是机器。如果机器成功伪装,让裁判分不清,它就算“通过”了测试。

b、ChatGPT 通过图灵测试了吗?

  • 在“行为表现”上部分通过(对非专业用户,短对话中可能被骗)。
  • 在“智能本质”上彻底失败(无意识、无理解、无真实意图)。

b、ChatGPT 的真相:“高明的模仿者”

  • 为什么它“看似通过”图灵测试?

    • 它被喂了万亿级人类对话数据,学会预测“人类接下来会说什么”。
    • 例如你问:“失恋了怎么办?” → 它调取数据库中高赞安慰话术,拼凑出“共情”回复。
    • 结果:普通人在短对话中容易被骗(尤其情绪脆弱时)。
  • 为什么它“根本没通过”本质测试?

    人类智能 ChatGPT(当前大模型) 验证案例
    理解上下文 仅记住最近几段对话(“上下文窗口”限制) 问:“刚才说的‘它’指什么?” → 常答错
    拥有常识 依赖训练数据,缺乏物理世界体验 问:“冰块放进热水会怎样?” → 可能说“融化”(但不懂热力学)
    真实意图 没有目标,只是响应输入 说“我想帮你” → 本质是概率生成,无“想”字含义
    情感体验 无感受,所有“共情”是预设话术 安慰你时,它甚至不知道“悲伤”是什么感觉

3、计算机的数学表示

1)计算机怎么存储信息?

计算机只能处理 0 和 1,所以一切都要变成数字。

阶段 方法 核心思想 优点 缺点 适用场景
1. 早期 ASCII 扩展 字符 → 数值 简单、高效 只支持单一语言 单一语言系统
2. 全球化 Unicode + UTF-8 全球统一编码 支持多语言 仅用于存储 所有现代系统
3. 机器学习 One-hot 每个词一个独热向量 简单直观 维度高、无语义 小规模任务
4. 深度学习 词嵌入(Embedding) 词 → 高维稠密向量 捕捉语义、高效 需要大量数据 大模型、推荐、搜索

a、从 ASCII 到深度学习

在上世纪 70 年代,计算机刚兴起时,主要用英文。为了表示字符,人们发明了 ASCII 码

  • 什么是 ASCII

    • 每个字符用 8 位二进制 表示(即 1 字节)

    • 只能表示 128 个字符(0~127)

    • 包括:英文字母 A-Z、a-z、数字 0-9、标点符号、控制字符

  • 优点:简单、统一、高效
  • 缺点:只能表示英文,没法表示中文、日文等

  • 解决方案:ASCII 扩展,为了支持其他语言,各地开发了自己的“扩展编码”:
编码 地区 特点
GB2312 中国大陆 支持简体中文,共 6763 个汉字
Big5 台湾地区 支持繁体中文,约 13000 个汉字
EUC-JP 日本 支持日文假名和汉字

b、UnicodeUTF-8:全球通用的字符编码

问题1:为什么需要 Unicode

答案:因为世界上的语言太多了,不能每个国家都搞一套自己的编码。于是,Unicode 应运而生

问题2:什么是 Unicode

答案:Unicode 是一个包含全世界所有字符的统一编码标准

优点:兼容 ASCII,节省空间,支持多语言

缺点:复杂,解析需额外逻辑

c、One-hot 编码(词汇表):机器学习中的第一代表示

问题1:为什么需要 One-hot

答案:计算机只能处理数字,所以必须把文字转成数值。早期方法:One-hot 编码

问题2: 什么是 One-hot

答案:把每个词表示为一个长度等于词汇表大小的向量,其中只有一个位置是 1,其余全是 0。

例子:假设词汇表有 5 个词:[“猫”, “狗”, “鱼”, “汽车”, “房子”]

  • “猫” → [1, 0, 0, 0, 0]

  • “狗” → [0, 1, 0, 0, 0]

  • “汽车” → [0, 0, 0, 1, 0]

类比:就像给每个人发一张 10 万人名单,只有自己名字打勾 → 你想知道谁和你“相似”?根本不可能!

问题 说明
维度太高 如果词汇表有 10 万个词 → 向量长度就是 10 万!内存吃不消
稀疏性严重 几乎全是 0,浪费计算资源
没有语义信息 “猫”和“狗”距离一样远,即使它们都是动物

优点:简单直观,容易计算

缺点:维度爆炸 + 无法捕捉语义关系

d、基于深度学习的语言模型:词嵌入(Word Embedding

问题1:为什么需要新方法?

答案:One-hot 太笨了!我们需要一种能自动学习语义关系的方法。于是,基于深度学习的词嵌入(Word Embedding 出现了。

问题2:什么是词嵌入?

答案:**将每个词映射到一个高维稠密向量(通常几百维),这个向量可以捕捉词语的语义信息。 **

优点:

  • 维度低(如 512 维),节省内存
  • 向量密集,便于计算
  • 相似词在空间中靠近 → 可以做语义搜索、类比推理

例子:

  • → “猫”和“狗”距离近 → 它们是同类
  • → “猫”和“汽车”距离远 → 不相关
向量(简化版)
[0.8, 0.2, 0.1]
[0.7, 0.3, 0.2]
[0.1, 0.8, 0.3]
汽车 [0.9, 0.1, 0.4]

为什么不能直接看数字大小?:只看某一个维度没意义!要看整体方向!

  • “猫”的第一个数是 0.8,“狗”是 0.7 → 很接近
  • “猫”和“汽车”第一个数都是 0.8 和 0.9 → 更接近?那为啥说“猫和汽车不相关”?

1)Embedding(嵌入)技术中最核心的数学操作

答案是:用“余弦相似度”(Cosine Similarity)

a、关键思想:看“方向”,不是看“位置”

Embedding 关心的是:两个向量在高维空间中的“夹角”

  • 夹角小 → 方向一致 → 语义相似
  • 夹角大 → 方向不同 → 语义无关

b、如何判断“近”还是“远”?

AI 的眼里,世界不是由词语组成的,而是由方向组成的。

‘猫’和‘狗’之所以近,不是因为它们长得像, 而是因为人类在千万次使用中,把它们放在了同一个‘语义方向’上。”

方法 说明
用余弦相似度 计算两个向量的夹角余弦值
看数值大小 > 0.7:很可能相关 0.3~0.7:弱相关 < 0.3:基本无关
不要信简化例子 教学用的低维向量会误导,真实 embedding 是高维的
语义决定方向 相似的事物,在高维空间中“指向同一片区域”

4、表示学习与嵌入

让机器“理解”语言的秘密武器

1)什么是“表示”?

“表示” = 把现实世界的东西(文字、图像、声音)转换成机器能计算的数字形式

人类 vs 机器

  • 人类看到“猫”,脑子里会浮现:毛茸茸、会叫、宠物、可爱……
  • 机器只认识数字。它看到“猫”,必须把它变成一串数字,才能处理。

2)早期方法:One-Hot 编码(为什么不够用?)

One-Hot 只知道“是不是这个词”,不知道“这个词是什么意思”。

1)方法:每个词一个“开关”

假设词汇表有 4 个词:[猫, 狗, 鱼, 汽车]

  • “猫” → [1, 0, 0, 0]
  • “狗” → [0, 1, 0, 0]
  • “汽车” → [0, 0, 0, 1]

2)优点:简单、直观

3) 缺点:没有语义信息!

4) 实验对比:

  • “猫” 和 “狗” 的距离 = √[(1-0)² + (0-1)² + …] = √2
  • “猫” 和 “汽车” 的距离 = √2

完全一样! 但现实中,“猫”和“狗”明明更像啊!

3)突破:表示学习(Representation Learning)

1)核心思想:不要人工设计表示,让机器自己从数据中“学会”如何表示!

这就像教小孩认字:

  • 不是告诉他“A 是第 65 个字母”
  • 而是让他在千万次阅读中,自然理解“A”出现在哪些词里、代表什么

2)真实案例:Word2Vec(2013 年)

谷歌提出 Word2Vec,训练模型预测上下文。

训练句子:“我喜欢吃苹果。

模型学到:

  • “吃” 周围常出现 “苹果”、“饭”、“面包” → 这些词向量接近
  • “我” 周围常出现 “喜欢”、“觉得”、“认为” → 这些词向量接近

结果惊人:

类比任务 模型输出
国王 - 男人 + 女人 = ? 女王
巴黎 - 法国 + 日本 = ? 东京

3)什么是“嵌入”(Embedding)?

Embedding = 一个低维稠密向量,用来表示某个对象(词、句子、用户、商品等)的“语义特征”

a、嵌入是表示学习的一种形式

1)大白话解释

  • 表示学习 = 教机器怎么“看懂”世界
  • 嵌入 = 其中一种最常用的方法,就像“翻译官”

2)类比:

  • 你去外国旅行,需要一个翻译器把中文变成英文
  • AI 中,“嵌入”就是那个翻译器,把“猫”变成“[0.8, 0.2, 0.1]”这样的向量

b、将高维数据映射到低维空间

目的:把高维稀疏的数据(比如 one-hot 编码)转化为低维稠密向量,保留语义信息。

1)什么是“高维数据”?

  • 举个例子:一个文档有 10000 个词 → 每个词都是一个维度 → 总共 10000 维
  • 这就是“高维数据” → 维度太多,计算慢,内存吃不消

2)什么是“低维空间”?

  • 把这 10000 维压缩成 512 维或 128 维
  • 保留关键信息,去掉冗余

c、嵌入可以是词嵌入、图像嵌入、图嵌入等”

不管是什么数据,都可以变成一个“向量”来表示其本质特征

三种常见类型:

类型 说明 例子
词嵌入(Word Embedding) 把词变成向量 “猫” → [0.8, 0.2, 0.1]
图像嵌入(Image Embedding) 把图片变成向量 一张猫的照片 → [0.7, 0.3, 0.9, …]
图嵌入(Graph Embedding) 把社交网络、知识图谱变成向量 “张三”和“李四”是朋友 → 向量接近

4)Word EmbeddingLanguage Model

  • 传统词嵌入(Word Embedding
    • 是静态的 → 一个词一个向量
    • 银行”永远是同一个意思(其实是“平均意思”)。
  • 现代语言模型(Language Model
    • 是动态的 → 同一个词,上下文不同,向量也不同
    • “河边的银行” = 河岸,“存钱的银行” = 金融机构。
传统方法 → Word Embedding → Language Model
   ↓          ↓             ↓
静态词向量 → 上下文无关 → 上下文相关 

5、表示学习怎么学

人类教 AI 的不是答案,而是‘理解的方式’。 —— 表示学习(Representation Learning)正是这一思想的核心。

让机器自己从数据中“学会”如何表示事物,而不是靠人手写规则。

  • 不告诉它“猫有什么特征”
  • 而是给它看几百万张带标签的图片,让它自己总结规律
  • 表示学习不是死记硬背,而是通过观察、比较、总结,自己学会“怎么看世界”。
问题 答案
表示学习是什么? 让机器自动学会如何用数字表示事物
怎么学? 通过上下文、对比、重构等方式
学什么? 语义、关系、风格、行为模式……
有什么用? 搜索、推荐、对话、分类、生成……
普通人能用吗? 能!OpenAI、HuggingFace 都提供现成 embedding

1)上下文预测 -> 看邻居学关系

“经常一起出现的东西,大概率有关系。”

  • “吃 ___” 后面常是“苹果”“饭” → 模型就把“吃”和“苹果”拉近。

  • 就像小孩听多了“爸爸开车”,就知道“爸爸”和“车”有关。

2)对比学习 -> 比着学差别

“相似的拉近,不同的推开。”

例子:同一张猫图变个角度,mbedding 要接近;猫图 vs 狗图,embedding 要远离。

像老师说:“这两张是一只猫,这张是狗——你要分清!”

3)自编码 -> 压缩再还原

能还原出来,说明你真懂了。

例子:把整段话压缩成一个短向量,再试着还原原文。还原得越准,说明这个向量抓到了重点。

就像让你用一句话总结电影——能说准,才算看懂。

二、实战 Embedding

1、准备工作

1)python安装

  1. 安装:brew install python

  2. 版本:python3 --version

  3. 路径:which python3

  4. 环境: ~/.bash.profile

    • alias python=python3
      alias pip=pip3
      
  5. pip list列出当前 Python 环境中已安装的所有第三方包(库)及其版本号

┌─[zhangyujin1@ZBMac-J7H7T2943L] - [/opt/homebrew] - [662]
└─[$] vim ~/.bash.profile                                                                          [14:53:25]
┌─[zhangyujin1@ZBMac-J7H7T2943L] - [/opt/homebrew] - [663]
└─[$] source ~/.bash.profile                                                                       [14:54:07]
┌─[zhangyujin1@ZBMac-J7H7T2943L] - [/opt/homebrew] - [664]
└─[$] python3 --version                                                                            [14:54:14]

Python 3.13.3
┌─[zhangyujin1@ZBMac-J7H7T2943L] - [/opt/homebrew] - [665]
└─[$] pip3 list                                                                                    [14:54:27]
Package Version
------- -------
pip     25.1.1
wheel   0.45.1

2)sentence-transformers python

sentence-transformers 能把任意一段文本(句子、段落、问题、文档)转换成一个固定长度的向量(比如 384 维、768 维),这个向量能“捕捉语义”,使得语义相近的句子在向量空间中距离很近。

  1. 基于预训练 Transformer 模型(如 BERT、RoBERTa、MPNet)
  2. 专门针对“句子对”任务微调(使用对比学习、孪生网络等技术)
  3. 输出池化后的句向量(不再是 token 级,而是整句级)
  4. 开箱即用:提供上百个在通用/多语言/特定领域微调好的模型
# 1. 创建一个专属虚拟环境(名字叫 venv,也可叫 myproject)
python3 -m venv venv

# 2. 激活虚拟环境
source venv/bin/activate

# 3. 现在 pip 安装就安全了!
pip3 install sentence-transformers

# 4、 升级 pip(可选但推荐)
pip install --upgrade pip

# 写代码...
python app.py

# 5、退出虚拟环境
deactivate

3)sentence-transformers 是大模型吗

你本地安装的是一个轻量级、免费、开源的“语义编码器”(embedding 模型),不是大语言模型,但它已经足够强大,能支撑搜索、推荐、RAG 等核心应用。不是用来生成文字的 AI,而是专门把文字变成向量的小模型

a、安装的是什么?

你运行这行代码时:

model = SentenceTransformer('BAAI/bge-small-zh-v1.5')

程序自动从 Hugging Face 下载了一个叫 bge-small-zh-v1.5 的模型。

  • 它是由 北京智源研究院(BAAI 开发的
  • 功能单一:只做一件事——把中文句子变成 512 维向量
  • 大小:约 100MB(非常小)
  • 类型:Embedding 模型,是表示学习模型,不是生成式大模型

b、它能聊天 or 写代码吗?

完全不能!这个模型没有生成能力,它只会:

输入:一段文字
输出:一个固定长度的数字列表(向量)

如果你想让它“回答问题”,必须搭配其他组件(比如 RAG + 大模型)。

2、实战-把中文变成向量

from sentence_transformers import SentenceTransformer

# 加载中文 embedding 模型(首次会自动下载,约 100MB)
model = SentenceTransformer('BAAI/bge-small-zh-v1.5')

# 输入任意中文
text = "我喜欢吃苹果。"

# 生成 embedding
embedding = model.encode(text)

print("向量长度:", len(embedding))  # 输出:512
print("前5个维度:", embedding[:5])
向量长度: 512
前5个维度: [-0.0111083   0.01596327  0.02920211  0.08485841 -0.03033804]

3、实战-相关文档搜索

目标:给定一个问题,从一堆文档中找出最相关的那篇。

  1. 先把所有文档都变成 embedding
  2. 用户输入问题:“我想养一只猫,有什么建议?”
  3. 计算用户问题和每篇文档的相似度
  4. 返回最接近的一篇
# ====== 相当于 Java 的 import ======
# 导入 SentenceTransformer 类(类似 Java 的 "import com.example.SentenceTransformer;")
# 这个库能将文本转换为语义向量(embedding)
from sentence_transformers import SentenceTransformer

# 导入 NumPy,用于高效数值计算(类似 Java 中用 double[] + MathUtils,但更强大)
import numpy as np


# ====== 初始化 AI 模型(相当于 new 一个预训练模型对象)======
# 加载一个专门针对中文优化的开源 embedding 模型
# 模型名称:'BAAI/bge-small-zh-v1.5'
# - BAAI:北京智源研究院开发
# - small:轻量版(速度快,内存小)
# - zh:支持中文
# - v1.5:版本号
# ⚠️ 首次运行会自动下载模型(约 100MB),之后就离线可用
model = SentenceTransformer('BAAI/bge-small-zh-v1.5')


# ====== 定义文档库(相当于 Java 中的 List<String> documents)======
documents = [
    "猫是一种可爱的宠物,喜欢抓老鼠。",
    "狗是人类最好的朋友,忠诚又聪明。",
    "苹果公司发布了新款 iPhone。",
    "我昨天在公园散步,看到一只小猫。"
]


# ====== 定义函数:将文本转为向量(相当于 Java 的 public double[] getEmbedding(String text))======
def get_embedding(text):
    """
    输入一段中文文本,返回它的语义向量(一个长度为 512 的 float 数组)
    内部调用 model.encode(),类似调用一个 AI 推理引擎
    """
    return model.encode(text)  # 返回类型:numpy.ndarray(可理解为 double[])


# ====== 定义函数:计算两个向量的余弦相似度(相当于 Java 工具方法)======
def cosine_sim(a, b):
    """
    计算两个向量 a 和 b 的余弦相似度
    公式:cosθ = (a·b) / (||a|| * ||b||)
    返回值范围:[-1, 1],越接近 1 表示语义越相似
    """
    # np.dot(a, b) → 向量点积(a·b)
    # np.linalg.norm(a) → 向量 a 的 L2 范数(即欧几里得长度 ||a||)
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))


# ====== 主逻辑开始 ======

# 1. 【批量编码】把所有文档转成向量(相当于 for 循环调用 getEmbedding)
# 结果:docs_embeddings 是一个列表,每个元素是一个 512 维向量
docs_embeddings = [get_embedding(doc) for doc in documents]
# ↑ 这是 Python 的“列表推导式”,等价于 Java:
# List<double[]> docsEmbeddings = documents.stream()
#     .map(this::getEmbedding)
#     .collect(Collectors.toList());


# 2. 用户提问(相当于 String query = "...")
query = "我想养一只猫,有什么建议?"


# 3. 把用户问题也转成向量
query_embedding = get_embedding(query)


# 4. 【计算相似度】遍历所有文档向量,计算与问题的相似度
# 结果:scores 是一个 float 列表,每个值表示对应文档的相关性
scores = [cosine_sim(query_embedding, doc_emb) for doc_emb in docs_embeddings]


# 5. 找出相似度最高的文档索引
# np.argmax(scores) → 返回 scores 中最大值的下标(int)
# int(...) → 显式转为 Python int(虽然通常不需要,但更清晰)
best_idx = int(np.argmax(scores))


# 6. 输出结果
print("最相关文档:")
print(documents[best_idx])      # 打印最相关的原始文本
print("相似度:", scores[best_idx])  # 打印相似度分数(比如 0.78)
最相关文档:
猫是一种可爱的宠物,喜欢抓老鼠。
相似度: 0.6237301

ContactAuthor