向量嵌入

嵌入 是指将高维数据(如非结构化文本)简化为维数较少的表示形式(如向量)。现代深度学习技术可以从文本和图像等非结构化数据创建向量嵌入(即结构化的数字表示形式),并在这些数据产生的向量几何中保留相似性和相异性的语义概念。

下图是自然语言文本的向量嵌入和几何相似性的简化示例。在实践中,神经网络产生的嵌入向量具有数百甚至数千个维度,而不是这里所示的两个维度,但概念是相同的。语义相似的文本产生“指向”相同的大致方向的向量。

向量相似性的二维示例

许多应用场景可以从查找与目标相似的文本或图像的功能中受益。例如,当新的支持工单记录到服务台时,支持团队可以从查找已解决的类似工单的功能中受益。在此应用场景中使用嵌入向量的好处是,它超越了关键字匹配而进化到语义相似性,因此,即使相关记录未确切包含相同的单词,也能找到这些记录。

Snowflake Cortex 提供用于创建嵌入的 EMBED_TEXT_768 (SNOWFLAKE.CORTEX) 函数,以及用于为各种应用场景比较嵌入的多个 向量相似性函数

关于向量相似性函数

向量之间的相似性度量是语义比较中的基本操作。Snowflake Cortex 提供了三个向量相似性函数:VECTOR_INNER_PRODUCT、VECTOR_L2_DISTANCE 和 VECTOR_COSINE_SIMILARITY。要了解有关这些函数的更多信息,请参阅 向量相似性函数

有关语法和用法的详细信息,请参阅每个函数的参考页面:

示例

以下示例使用向量相似性函数。

此 SQL 示例使用 VECTOR_INNER_PRODUCT 函数来确定表中的哪些向量在列 a 和列 b 之间彼此最接近:

CREATE TABLE vectors (a VECTOR(float, 3), b VECTOR(float, 3));
INSERT INTO vectors SELECT [1.1,2.2,3]::VECTOR(FLOAT,3), [1,1,1]::VECTOR(FLOAT,3);
INSERT INTO vectors SELECT [1,2.2,3]::VECTOR(FLOAT,3), [4,6,8]::VECTOR(FLOAT,3);

-- Compute the pairwise inner product between columns a and b
SELECT VECTOR_INNER_PRODUCT(a, b) FROM vectors;
Copy
+------+
| 6.3  |
|------|
| 41.2 |
+------+

此 SQL 示例调用 VECTOR_COSINE_SIMILARITY 函数查找接近 [1,2,3] 的向量:

SELECT a, VECTOR_COSINE_SIMILARITY(a, [1,2,3]::VECTOR(FLOAT, 3)) AS similarity
    FROM vectors
ORDER BY similarity DESC
LIMIT 1;
Copy
+-------------------------+
| [1, 2.2, 3] | 0.9990... |
+-------------------------+

Snowflake Python Connector

这些示例展示了如何将 VECTOR 数据类型和向量相似性函数与 Python Connector 一起使用。

备注

Snowflake Python Connector 版本 3.6 中引入了对 VECTOR 类型的支持。

import snowflake.connector

conn = ... # Set up connection
cur = conn.cursor()

# Create a table and insert some vectors
cur.execute("CREATE OR REPLACE TABLE vectors (a VECTOR(FLOAT, 3), b VECTOR(FLOAT, 3))")
values = [([1.1, 2.2, 3], [1, 1, 1]), ([1, 2.2, 3], [4, 6, 8])]
for row in values:
        cur.execute(f"""
            INSERT INTO vectors(a, b)
                SELECT {row[0]}::VECTOR(FLOAT,3), {row[1]}::VECTOR(FLOAT,3)
        """)

# Compute the pairwise inner product between columns a and b
cur.execute("SELECT VECTOR_INNER_PRODUCT(a, b) FROM vectors")
print(cur.fetchall())
Copy
[(6.30...,), (41.2...,)]
# Find the closest vector to [1,2,3]
cur.execute(f"""
    SELECT a, VECTOR_COSINE_SIMILARITY(a, {[1,2,3]}::VECTOR(FLOAT, 3))
        AS similarity
        FROM vectors
        ORDER BY similarity DESC
        LIMIT 1;
""")
print(cur.fetchall())
Copy
[([1.0, 2.2..., 3.0], 0.9990...)]

Snowpark Python

这些示例展示了如何将 VECTOR 数据类型和向量相似性函数与 Snowpark Python 库一起使用。

备注

  • Snowpark Python 版本 1.11 中引入了对 VECTOR 类型的支持。

  • Snowpark Python 库不支持 VECTOR_COSINE_SIMILARITY 函数。

from snowflake.snowpark import Session, Row
session = ... # Set up session
from snowflake.snowpark.types import VectorType, StructType, StructField
from snowflake.snowpark.functions import col, lit, vector_l2_distance
schema = StructType([StructField("vec", VectorType(int, 3))])
data = [Row([1, 2, 3]), Row([4, 5, 6]), Row([7, 8, 9])]
df = session.create_dataframe(data, schema)
df.select(
    "vec",
    vector_l2_distance(df.vec, lit([1, 2, 2]).cast(VectorType(int, 3))).as_("dist"),
).sort("dist").limit(1).show()
Copy
----------------------
|"VEC"      |"DIST"  |
----------------------
|[1, 2, 3]  |1.0     |
----------------------

从文本创建向量嵌入

重要

snowflake-arctic-embed-me5-base-v2 模型的输入限制为 512 个词元。某些词元并不表示单词,因此支持的单词数会略少。如果文本过长,您将收到错误消息。

要从一段文本创建向量嵌入,请使用 EMBED_TEXT_768 (SNOWFLAKE.CORTEX) 函数。此函数返回给定英语文本的向量嵌入。此向量可与 向量比较函数 一起使用,以确定两个文档的语义相似性。

SELECT SNOWFLAKE.CORTEX.EMBED_TEXT_768(model, text)
Copy

小技巧

您可以通过 Snowpark Container Services 使用其他嵌入模型。有关更多信息,请参阅 嵌入文本容器服务 (https://github.com/Snowflake-Labs/sfguide-text-embedding-snowpark-container-service)。

重要

EMBED_TEXT_768 是 Cortex LLM 函数,因此,使用此函数时要遵守与其他 Cortex LLM 函数相同的访问控制。有关访问这些函数的说明,请参阅 Cortex LLM 函数所需权限

用例示例

本部分介绍如何使用嵌入、向量相似性函数和 VECTOR 数据类型来实现常见用例,如向量相似性搜索和检索增强生成 (RAG)。

检索增强生成 (RAG)

在检索增强生成 (RAG) 中,用户的查询用于使用 向量相似性 查找相似的文档。然后,顶层文档与用户的查询一起传递给大型语言模型 (LLM),为生成式响应(完成)提供上下文。 这可以大大提高响应的适当性。

在下面的示例中,wiki 是具有文本列 content 的表,query 是具有文本列 text 的单行表。

-- Create embedding vectors for wiki articles (only do once)
ALTER TABLE wiki ADD COLUMN vec VECTOR(FLOAT, 768);
UPDATE wiki SET vec = SNOWFLAKE.CORTEX.EMBED_TEXT_768('snowflake-arctic-embed-m', content);

-- Embed incoming query
SET query = 'in which year was Snowflake Computing founded?';
CREATE OR REPLACE TABLE query_table (query_vec VECTOR(FLOAT, 768));
INSERT INTO query_table SELECT SNOWFLAKE.CORTEX.EMBED_TEXT_768('snowflake-arctic-embed-m', $query);

-- Do a semantic search to find the relevant wiki for the query
WITH result AS (
    SELECT
        w.content,
        $query AS query_text,
        VECTOR_COSINE_SIMILARITY(w.vec, q.query_vec) AS similarity
    FROM wiki w, query_table q
    ORDER BY similarity DESC
    LIMIT 1
)

-- Pass to large language model as context
SELECT SNOWFLAKE.CORTEX.COMPLETE('mistral-7b',
    CONCAT('Answer this question: ', query_text, ' using this text: ', content)) FROM result;
Copy

成本注意事项

Snowflake Cortex LLM 函数(包括 EMBED_TEXT_768)根据处理的词元数产生计算成本。下表显示了每个函数每 100 万个词元的 credit 成本。

备注

词元是 Snowflake Cortex LLM 函数处理的最小文本单位,大约等于四个字符的文本。原始输入或输出文本与词元的等价性可能因模型而异。

  • 对于 EMBED_TEXT_768 函数,仅将输入词元计入可计费总额。

  • 向量相似性函数不会产生基于词元的成本。

有关 Cortex LLM 函数计费的更多信息,请参阅 Cortex LLM 函数成本注意事项。有关计算成本的一般信息,请参阅 了解计算成本

语言: 中文