wikivec2text
用GPT-2微调实现句子嵌入向量算数,验证类比推理能力
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
用GPT-2微调实现句子嵌入向量算数,验证类比推理能力
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
如果你熟悉 NLP 历史,一定记得 word2vec 最令人兴奋的特性之一:向量算术。最经典的例子就是 vec("king") - vec("man") + vec("woman") ≈ vec("queen") —— 仅通过向量的加减法,就能让模型"推理"出词语之间的语义关系,而无需任何显式规则。
这一发现点燃了 2013 年的 NLP 社区,也让"分布式语义假说"深入人心。
然而,word2vec 处理的是单词。当我们想把同样的思路迁移到句子级别时,问题变得复杂得多:句子更长、语义更丰富、语法结构更多变,简单的词向量平均根本无法保留这些信息。直到 OpenAI 推出 text-embedding-ada-002 这样强大的句子嵌入模型,给句子做向量算术才重新成为可能。
而 wikivec2text 正是这个方向的极简验证器:它用 Ada 嵌入向量做加减法,再把这个向量"翻译"回自然语言句子——就像给 GPT-2 模型装上了一个"向量到文本"的解码器。
图1:项目作者 MF-FOOM 的 GitHub 头像
wikivec2text 的作者 @MF_FOOM 于 2023 年 8 月在 Twitter 分享了这个项目,帖子迅速获得了关注。他只用了不到 500 行代码,在一小批(约 700 万条)Wikipedia 句子嵌入上微调了 GPT-2-small,就成功复现了类似 word2vec 的句子级算术能力。
核心实验逻辑(来自 test.py)非常直观:
# 用 embedding 做向量加减法
embedding = embed("Revolver is the seventh album by the Beatles.") \
- embed("The Beatles are a rock band.") \
+ embed("The Beatles are a classical band.")
# 模型将向量解码为文本
print(enc.decode(model.generate(embedding, max_new_tokens=100).tolist()))
这一行代码展示了项目的全部魔力:给定一个"修改过"的句子嵌入,模型能生成语义上与修改方向一致的新句子。
wikivec2text 的代码骨架直接基于 Andrej Karpathy 的 nanoGPT,这是一份简洁易懂的 GPT-2 实现。项目的核心创新在于 AdaProjectionMLP 层——这是一个额外的 MLP 模块,位于标准 GPT 架构之前,作用是将 text-embedding-ada-002 输出的 1536 维向量投影到 GPT-2 的隐藏维度空间。
模型配置(GPTConfig):
| 参数 | 值 | 说明 |
|---|---|---|
n_layer | 12 | 层数,等同 GPT-2 Small |
n_head | 12 | 注意力头数 |
n_embd | 768 | 嵌入维度 |
block_size | 1024 | 最大上下文长度 |
ada_dims | 1536 | Ada 嵌入维度(输入) |
projection_scale | 50 | 投影放大系数 |
vocab_size | 50304 | GPT-2 词表大小 |
模型规模约 124M 参数(与标准 GPT-2 Small 相当)。项目使用 Flash Attention(PyTorch 2.0+)加速推理,并实现了权重绑定(weight tying)——将输入词嵌入和输出 LM 头共享。
核心模块解析:
exec(open(...).read()) 动态加载配置,避免 YAML/TOML 解析依赖。训练数据:约 700 万条 Wikipedia 句子(来自 Kaggle 数据集 wikipedia-sentences),由 text-embedding-ada-002 编码为 1536 维向量。每个句子对应一个向量,项目要学的任务是:给定这个向量,重建原句子。
与标准语言建模的区别:传统 GPT 是 P(x₂|x₁) 的概率模型,而 wikivec2text 的输入是向量而非 token,目标是根据向量内容恢复与之对应的文本序列。这本质上是将一个检索/解码任务建模为生成任务。
适用场景:
重要局限(README 原文警告):
由于训练数据高度结构化(百科全书风格的正式句子),模型极易在分布外(OOD)样本上失效。使用时需确保:
- 句子必须以大写字母开头
- 必须以句号结尾
- 内容必须是信息性陈述句
- 避免口语化表达
项目代码极简,核心文件只有 4 个,依赖清晰,适合作为 nanoGPT 学习素材:
pip install torch openai tiktoken transformers huggingface_hub
export OPENAI_API_KEY=sk-...
python test.py
模型 checkpoint 托管在 HuggingFace Hub(MF-FOOM/wikivec2text),通过 hf_hub_download 自动拉取。
wikivec2text 的意义不在于"做到SOTA",而在于极简验证:用最少的代码、最小的数据量,证明了句子嵌入可以做算术运算并解码回自然语言。这种"概念验证"风格是开源社区最珍贵的精神之一。
从更大的视角看,这个项目呼应了一个趋势:将强大的 embedding 模型作为推理引擎的输入,而不仅仅是用于相似度计算。它暗示了一种可能性—— embedding 不只是"数字表示",而是可以作为可编程的语义指令。如果你对 nanoGPT、GPT-2 架构、embedding 算术感兴趣,wikivec2text 是绝佳的学习起点。