Embedding 向量嵌入 获取给定输入的向量表示,可以轻松被机器学习模型和算法使用。 什么是嵌入向量? 嵌入向量是浮点数的向量(列表),用于衡量文本字符串的相关性。两个向量之间的距离衡量它们的相关性:小距离表示高相关性,大距离表示低相关性。 嵌入通常用于: 搜索 - 结果按与查询字符串的相关性排序 聚类 - 文本字符串按相似性分组 推荐 - 推荐具有相关文本字符串的项目 异常检测 - 识别相关性较低的异常值 分类 - 文本字符串按其最相似的标签分类 快速开始 安装 SDK pip install openai 基础示例 请确保将 $MODELVERSE_API_KEY 替换为您自己的 API Key,获取 API Key。 Python from openai import OpenAI client = OpenAI( api_key="YOUR_MODELVERSE_API_KEY", base_url="https://api.modelverse.cn/v1" ) response = client.embeddings.create( input="Your text string goes here", model="text-embedding-3-large" ) print(response.data[0].embedding) curl curl https://api.modelverse.cn/v1/embeddings \ -H "Authorization: Bearer $MODELVERSE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Your text string goes here", "model": "text-embedding-3-large" }' 响应包含嵌入向量(浮点数列表)以及一些附加元数据。您可以提取嵌入向量,将其保存在向量数据库中,并用于许多不同的用例。 API 参考 POST https://api.modelverse.cn/v1/embeddings 请求参数 参数类型必填说明inputstring 或 array是要嵌入的输入文本,编码为字符串或 token 数组。要在单个请求中嵌入多个输入,请传递字符串数组。输入不得超过 8192 个 token,不能为空字符串。单个请求中所有输入的 token 总和最多为 300,000 个。modelstring是要使用的模型 ID,如 text-embedding-3-large。dimensionsinteger否生成的输出嵌入向量应具有的维度数。仅在 text-embedding-3 及更高版本的模型中支持。encoding_formatstring否返回嵌入向量的格式。可以是 float 或 base64。默认值:float 响应示例 { "object": "list", "data": [ { "object": "embedding", "embedding": [0.0023064255, -0.009327292, ..., -0.0028842222], "index": 0 } ], "model": "text-embedding-3-large", "usage": { "prompt_tokens": 8, "total_tokens": 8 } } 响应字段说明 字段类型说明embeddingarray嵌入向量,是一个浮点数列表。向量的长度取决于模型。indexinteger嵌入在嵌入列表中的索引。objectstring对象类型,始终为 “embedding”。 嵌入模型 模型默认维度最大输入MTEB 评估性能text-embedding-3-large3072819264.6%text-embedding-ada-0021536819261.0% 降低嵌入维度 使用较大的嵌入向量通常成本更高,消耗更多的计算、内存和存储。您可以通过传入 dimensions 参数来缩短嵌入维度,而不会丢失嵌入的概念表示属性。 例如,text-embedding-3-large 嵌入可以缩短到 256 维,同时仍然优于 1536 维的 text-embedding-ada-002。 Python from openai import OpenAI client = OpenAI( api_key="YOUR_MODELVERSE_API_KEY", base_url="https://api.modelverse.cn/v1" ) response = client.embeddings.create( model="text-embedding-3-large", input="Testing 123", dimensions=256 # 指定输出维度 ) print(response.data[0].embedding) curl curl https://api.modelverse.cn/v1/embeddings \ -H "Authorization: Bearer $MODELVERSE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "input": "Testing 123", "model": "text-embedding-3-large", "dimensions": 256 }' 手动归一化维度 如果需要手动截断并归一化嵌入向量: from openai import OpenAI import numpy as np client = OpenAI( api_key="YOUR_MODELVERSE_API_KEY", base_url="https://api.modelverse.cn/v1" ) def normalize_l2(x): x = np.array(x) if x.ndim == 1: norm = np.linalg.norm(x) if norm == 0: return x return x / norm else: norm = np.linalg.norm(x, 2, axis=1, keepdims=True) return np.where(norm == 0, x, x / norm) response = client.embeddings.create( model="text-embedding-3-large", input="Testing 123", encoding_format="float" ) cut_dim = response.data[0].embedding[:256] norm_dim = normalize_l2(cut_dim) print(norm_dim) 使用场景 1. 文本搜索 使用查询的嵌入向量和每个文档之间的余弦相似度,返回得分最高的文档。 from openai import OpenAI import numpy as np client = OpenAI( api_key="YOUR_MODELVERSE_API_KEY", base_url="https://api.modelverse.cn/v1" ) def cosine_similarity(a, b): return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)) def get_embedding(text, model="text-embedding-3-large"): response = client.embeddings.create(input=text, model=model) return response.data[0].embedding def search_documents(documents, query, n=3): query_embedding = get_embedding(query) results = [] for doc in documents: doc_embedding = get_embedding(doc) similarity = cosine_similarity(query_embedding, doc_embedding) results.append((doc, similarity)) results.sort(key=lambda x: x[1], reverse=True) return results[:n] # 示例 documents = ["Python 是一种编程语言", "机器学习很有趣", "今天天气很好"] results = search_documents(documents, "编程") print(results) 2. 基于嵌入的问答 将相关文档放入模型的上下文窗口中进行问答。 from openai import OpenAI client = OpenAI( api_key="YOUR_MODELVERSE_API_KEY", base_url="https://api.modelverse.cn/v1" ) # 假设已通过嵌入搜索找到相关文章 relevant_article = "2022年冬季奥运会冰壶金牌由..." query = f"""使用以下文章回答问题。如果找不到答案,请写"我不知道。" 文章: \"\"\" {relevant_article} \"\"\" 问题:哪些运动员在 2022 年冬季奥运会上获得了冰壶金牌? """ response = client.chat.completions.create( messages=[ {'role': 'system', 'content': ‘你回答有关 2022 年冬季奥运会的问题。’}, {'role': 'user', 'content': query}, ], model="gpt-4o", temperature=0, ) print(response.choices[0].message.content) 3. 聚类分析 使用嵌入向量对文本进行聚类分组。 import numpy as np from sklearn.cluster import KMeans # 假设 embeddings 是已获取的嵌入向量列表 embeddings = [...] # 从 API 获取的嵌入向量 matrix = np.vstack(embeddings) n_clusters = 4 kmeans = KMeans( n_clusters=n_clusters, init='k-means++', random_state=42 ) kmeans.fit(matrix) # 每个文本的聚类标签 labels = kmeans.labels_ 4. 推荐系统 基于嵌入向量的相似度进行推荐。 from openai import OpenAI import numpy as np client = OpenAI( api_key="YOUR_MODELVERSE_API_KEY", base_url="https://api.modelverse.cn/v1" ) def get_embedding(text, model="text-embedding-3-large"): response = client.embeddings.create(input=text, model=model) return response.data[0].embedding def recommend_similar(items, source_index, n=3): """返回与源项目最相似的 n 个项目""" embeddings = [get_embedding(item) for item in items] source_embedding = embeddings[source_index] similarities = [] for i, emb in enumerate(embeddings): if i != source_index: sim = np.dot(source_embedding, emb) similarities.append((i, items[i], sim)) similarities.sort(key=lambda x: x[2], reverse=True) return similarities[:n] 5. 零样本分类 无需训练数据,使用嵌入进行分类。 from openai import OpenAI import numpy as np client = OpenAI( api_key="YOUR_MODELVERSE_API_KEY", base_url="https://api.modelverse.cn/v1" ) def get_embedding(text, model="text-embedding-3-large"): response = client.embeddings.create(input=text, model=model) return response.data[0].embedding def cosine_similarity(a, b): return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)) def classify_text(text, labels): text_embedding = get_embedding(text) label_embeddings = [get_embedding(label) for label in labels] similarities = [cosine_similarity(text_embedding, le) for le in label_embeddings] best_index = np.argmax(similarities) return labels[best_index] # 示例 labels = ["positive", "negative", "neutral"] result = classify_text("这个产品太棒了!", labels) print(result) # 输出: positive 常见问题 如何计算字符串的 token 数量? 使用 OpenAI 的分词器 tiktoken: import tiktoken def num_tokens_from_string(string: str, encoding_name: str = "cl100k_base") -> int: """返回文本字符串中的 token 数量。""" encoding = tiktoken.get_encoding(encoding_name) num_tokens = len(encoding.encode(string)) return num_tokens print(num_tokens_from_string("tiktoken is great!")) # 输出: 4 对于第三代嵌入模型(如 text-embedding-3-large),使用 cl100k_base 编码。 如何快速检索 K 个最近的嵌入向量? 为了快速搜索大量向量,建议您使用向量数据库,如: AI 数据库(参考文档:AI数据库) pgvector (参考文档:PostgreSQL 应该使用哪个距离函数? 推荐使用余弦相似度。OpenAI 嵌入已归一化为长度 1,这意味着: 余弦相似度可以仅使用点积计算,速度更快 余弦相似度和欧几里得距离将产生相同的排名