前言
看下面这段例子
from sentence_transformers import SentenceTransformer
import faiss
from transformers import GPT2LMHeadModel, GPT2Tokenizer
# 数据向量化
embedder = SentenceTransformer('paraphrase-MiniLM-L6-v2')
data = ["LangChain is a framework for building applications with large language models.",
"Machine learning is fun"]
data_embeddings = embedder.encode(data)
# 向量化检索
index = faiss.IndexFlatL2(data_embeddings.shape[1])
index.add(data_embeddings)
query = "What is LangChain?"
query_embedding = embedder.encode([query])
D, I = index.search(query_embedding, k=1)
retrieved_doc = data[I[0][0]]
# 结果梳理
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
model = GPT2LMHeadModel.from_pretrained('gpt2')
input_ids = tokenizer.encode(f"{retrieved_doc} Answer the question: {query}", return_tensors='pt')
output = model.generate(input_ids, max_length=50)
answer = tokenizer.decode(output[0], skip_special_tokens=True)
print(answer)
看其中的 input_ids = tokenizer.encode(f"{retrieved_doc} Answer the question: {query}", return_tensors=‘pt’),看见encode就知道是在转换明文。那转换的结果是什么呢?是不是在做向量嵌入呢?encode之后的结果为什么能直接给模型处理呢?
一、什么是Token id
1. 概念
Token ID 序列 是模型词汇表中每个词或子词的索引,用于语言模型的输入。
它返回的是整数数组,每个整数是词汇表中对应词的索引。
2. 用途
Token ID 序列是在大型语言模型内部使用的,它们对应着模型的词汇表中的词或子词的索引,用于将输入文本映射到模型的隐藏状态。这些隐藏状态包含了输入文本的语义信息,模型在此基础上进行后续的处理,比如生成、分类、相似性计算等。
Token ID 序列在模型内部的使用过程如下:
1)模型的输入层接收到 Token ID 序列。
2)模型根据这些 Token ID 查找对应的词嵌入(embedding)向量。
3)这些词嵌入向量经过模型的各个层级,逐渐形成对输入文本的理解。
4) 最终,模型在输出层产生相应的结果,比如生成文本、文本分类、问答等。
Token ID 序列可以被看作是模型理解输入文本的一种中间表示形式,它提供了一种方便的方式将文本转化为模型可以理解的格式,从而进行进一步的处理和分析。
3. 举例
这个例子使用了 Hugging Face 的 transformers
库中的 BERT 模型的 tokenizer。这个 tokenizer 的 .encode
方法将输入字符串转换为一系列的 token IDs,这些 IDs 是 BERT 词汇表中对应的整数索引。
from transformers import BertTokenizer
# 加载BERT的tokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
# 输入字符串
input_text = "Hello world"
# 获取Token ID序列
input_ids = tokenizer.encode(input_text, add_special_tokens=True)
print("Input Text:", input_text)
print("Token IDs:", input_ids)
5. 输出解析
input_text
是原始的输入字符串。input_ids
是该字符串转换后的 Token ID 序列。例如,"Hello world"
可能会被转换成[101, 7592, 2088, 102]
,其中101
和102
是特殊的 [CLS] 和 [SEP] 标记,7592
和2088
分别是Hello
和world
在 BERT 词汇表中的索引。
二、什么是嵌入向量
嵌入向量 是通过嵌入模型生成的连续向量,捕捉输入字符串的语义信息,用于相似性计算和检索。表示输入文本在嵌入空间中的位置。
它返回的是浮点数数组,表示输入文本的语义信息。
1. 代码示例
from langchain.embeddings import OpenAIEmbeddings
# 创建OpenAIEmbeddings实例
embeddings = OpenAIEmbeddings()
# 示例文档内容
doc = {
"page_content": "LangChain is a framework for building applications with large language models."
}
# 将文档内容转换为向量
vector = embeddings.embed(doc["page_content"])
print("Document content:", doc["page_content"])
print("Embedding vector:", vector)
2. 详细说明
- 导入库:导入
OpenAIEmbeddings
类,该类用于生成嵌入向量。 - 创建实例:实例化
OpenAIEmbeddings
对象,准备进行文本嵌入。 - 嵌入转换:使用
embed
方法将文档内容(doc.page_content
)转换为嵌入向量。 - 向量vector 格式形如
[0.123, -0.456, ..., 0.789]
,是一个高维的浮点数数组,表示输入字符串在嵌入空间中的位置。
3. 嵌入向量的用途
- 语义相似性:嵌入向量可以用来计算文本之间的相似性,便于检索相关文档。
- 分类任务:嵌入向量可以作为输入特征,用于分类或聚类任务。
- 信息检索:在大规模文档库中,通过计算向量相似性来快速检索相关信息。
- 推荐系统:通过嵌入向量表示用户和物品,实现内容推荐。
总结
大模型的很多东西有些相似,不仔细研究,光看两者的结果 [101, 7592, 2088, 102]
和[0.123, -0.456, ..., 0.789]
也很相似。导致我们不去深究的话会把它们弄混,后面也容易输入错的的参数。