使用CLI进行嵌入#

LLM 提供了命令行工具,用于计算和存储内容片段的嵌入。

llm 嵌入#

llm embed 命令可用于计算内容字符串的嵌入向量。这些向量可以直接返回到终端,存储在 SQLite 数据库中,或者两者兼而有之。

将嵌入返回到终端#

使用此命令的最简单方法是通过-c/--content选项传递内容,如下所示:

llm embed -c 'This is some content' -m 3-small

-m 3-small 指定了OpenAI的text-embedding-3-small模型。你需要使用llm keys set openai设置一个OpenAI API密钥才能使其工作。

您可以安装插件以访问其他模型。llm-sentence-transformers插件可用于在您自己的笔记本电脑上运行模型,例如MiniLM-L6模型:

llm install llm-sentence-transformers
llm embed -c 'This is some content' -m sentence-transformers/all-MiniLM-L6-v2

llm embed 命令直接返回一个浮点数数组的 JSON 数组到终端:

[0.123, 0.456, 0.789...]

如果您设置了默认嵌入模型,则可以省略-m/--model选项。

LLM 还为嵌入提供了一种二进制存储格式,详情请参阅 embeddings storage format

您可以使用--format blob以原始字节格式输出嵌入,或使用--format hex以十六进制格式输出,或使用--format base64以Base64格式输出:

llm embed -c 'This is some content' -m 3-small --format base64

这输出:

8NGzPFtdgTqHcZw7aUT6u+++WrwwpZo8XbSxv...

一些模型如llm-clip可以处理二进制数据。你可以使用-i--binary选项传入二进制数据:

llm embed --binary -m clip -i image.jpg

或者像这样从标准输入:

cat image.jpg | llm embed --binary -m clip -i -

在SQLite中存储嵌入#

如果你将嵌入存储在某个地方,它们会更有用,这样你以后可以计算不同嵌入之间的相似度分数。

LLM 包含了集合的概念。一个集合将一组使用相同模型创建的存储嵌入分组在一起,每个嵌入在该集合中都有一个唯一的ID。

嵌入还存储了被嵌入内容的哈希值。此哈希值随后用于避免为相同内容计算重复的嵌入。

首先,我们将设置一个默认模型,这样我们就不必一直重复它:

llm embed-models default 3-small

llm embed 命令可以直接将结果存储在命名的集合中,如下所示:

llm embed quotations philkarlton-1 -c \
  'There are only two hard things in Computer Science: cache invalidation and naming things'

这将给定的文本存储在quotations集合中,键为philkarlton-1

你也可以将内容通过管道传输到标准输入,如下所示:

cat one.txt | llm embed files one

这将存储one.txt内容的嵌入到files集合中,键为one

第一次提到集合时将会创建它。

集合有一个固定的嵌入模型,这是用于存储在该集合中的第一个嵌入的模型。

在上面的例子中,这将是运行命令时的默认嵌入模型。

以下示例将字符串“my happy hound”的嵌入存储在名为phrases的集合中,键为hound,并使用模型3-small

llm embed phrases hound -m 3-small -c 'my happy hound'

默认情况下,用于存储嵌入的SQLite数据库是由LLM管理的用户内容目录中的embeddings.db

你可以通过运行llm collections path来查看此目录的路径。

您可以通过使用-d/--database选项将路径传递给llm embed,将嵌入存储在不同的SQLite数据库中。如果该文件尚不存在,命令将创建它:

llm embed phrases hound -d my-embeddings.db -c 'my happy hound'

这将在当前目录中创建一个名为my-embeddings.db的数据库文件。

存储内容和元数据#

默认情况下,只有条目ID和嵌入向量存储在数据库表中。

您可以通过传递--store选项将原始文本的副本存储在content列中:

llm embed phrases hound -c 'my happy hound' --store

你也可以通过传递--metadata选项,在metadata列中存储包含任意元数据的JSON对象。这个例子同时使用了--store--metadata选项:

llm embed phrases hound \
  -m 3-small \
  -c 'my happy hound' \
  --metadata '{"name": "Hound"}' \
  --store

以这种方式存储的数据将通过调用llm similar返回,例如:

llm similar phrases -c 'hound'
{"id": "hound", "score": 0.8484683588631485, "content": "my happy hound", "metadata": {"name": "Hound"}}

llm embed-multi#

llm embed 命令一次嵌入一个字符串。

llm embed-multi 可以用于一次性嵌入多个字符串,利用嵌入模型在处理多个字符串时可能提供的任何效率优势。

此命令可以通过以下三种方式之一调用:

  1. 使用CSV、TSV、JSON或换行符分隔的JSON文件

  2. 使用SQLite数据库和SQL查询

  3. 带有一个或多个目录路径,每个路径都附带一个通配符模式

所有三种机制都支持这些选项:

  • -m model_id 用于指定要使用的嵌入模型

  • -d database.db 指定一个不同的数据库文件来存储嵌入

  • --store 除了嵌入向量外,还将原始内容存储在嵌入表中

  • --prefix 为每个项目的存储ID添加前缀

  • --prepend 在嵌入之前将字符串添加到内容的前面

  • --batch-size SIZE 以指定大小的批次处理嵌入

--prepend 选项对于需要嵌入模型时在内容前添加特殊标记的情况非常有用。例如,nomic-embed-text-v2-moe 要求文档前添加 'search_document: ',搜索查询前添加 'search_query: '

从CSV、TSV或JSON文件中嵌入数据#

您可以通过将CSV、TSV或JSON文件作为第二个选项传递给命令,在集合名称之后嵌入数据。

您的文件必须包含至少两列。第一列应包含项目的ID,任何后续列将被视为包含要嵌入的内容。

一个CSV文件的示例可能如下所示:

id,content
one,This is the first item
two,This is the second item

TSV 将使用制表符而不是逗号。

JSON 文件可以这样结构化:

[
  {"id": "one", "content": "This is the first item"},
  {"id": "two", "content": "This is the second item"}
]

或者像这样的换行分隔的JSON:

{"id": "one", "content": "This is the first item"}
{"id": "two", "content": "This is the second item"}

在每种情况下,文件都可以像这样传递给 llm embed-multi

llm embed-multi items mydata.csv

第一个参数是集合的名称,第二个是文件名。

你也可以使用-将内容通过管道传输到工具的标准输入:

cat mydata.json | llm embed-multi items -

LLM 将尝试自动检测您的数据格式。如果这不起作用,您可以使用 --format 选项指定格式。如果您将换行符分隔的 JSON 通过管道传输到标准输入,则这是必需的。

cat mydata.json | llm embed-multi items - --format nl

其他支持的--format选项有csvtsvjson

此示例将来自JSON文件的数据嵌入到名为items的集合中,该集合位于名为docs.db的数据库中,使用3-small模型,并将原始内容存储在embeddings表中,同时为每个ID添加my-items/前缀:

llm embed-multi items mydata.json \
  -d docs.db \
  -m 3-small \
  --prefix my-items/ \
  --store

从SQLite数据库嵌入数据#

你可以使用--sql从SQLite数据库中嵌入数据,也可以选择与--attach结合使用以附加额外的数据库。

如果您将嵌入存储在源数据的同一数据库中,您可以这样做:

llm embed-multi docs \
  -d docs.db \
  --sql 'select id, title, content from documents' \
  -m 3-small

这里的docs.db数据库包含一个documents表,我们想要嵌入该表中的titlecontent列,并将结果存储回同一个数据库中。

要从不同于用于存储嵌入的数据库中加载内容,请使用--attach选项附加它,并在SQLite查询中使用alias.table

llm embed-multi docs \
  -d embeddings.db \
  --attach other other.db \
  --sql 'select id, title, content from other.documents' \
  -m 3-small

从目录中的文件嵌入数据#

LLM 可以将指定目录中每个文本文件的内容嵌入,使用文件的路径和名称作为ID。

考虑一个像这样的目录结构:

docs/aliases.md
docs/contributing.md
docs/embeddings/binary.md
docs/embeddings/cli.md
docs/embeddings/index.md
docs/index.md
docs/logging.md
docs/plugins/directory.md
docs/plugins/index.md

要嵌入所有这些文档,您可以运行以下内容:

llm embed-multi documentation \
  -m 3-small \
  --files docs '**/*.md' \
  -d documentation.db \
  --store

这里 --files docs '**/*.md' 指定应该扫描 docs 目录以查找与 **/*.md 通配符模式匹配的文件 - 这将匹配任何嵌套目录中的Markdown文件。

上述命令的结果是一个带有以下ID的embeddings表:

aliases.md
contributing.md
embeddings/binary.md
embeddings/cli.md
embeddings/index.md
index.md
logging.md
plugins/directory.md
plugins/index.md

每个对应于相关文件的嵌入内容。

--prefix 选项可用于为每个ID添加前缀:

llm embed-multi documentation \
  -m 3-small \
  --files docs '**/*.md' \
  -d documentation.db \
  --store \
  --prefix llm-docs/

这将导致以下ID:

llm-docs/aliases.md
llm-docs/contributing.md
llm-docs/embeddings/binary.md
llm-docs/embeddings/cli.md
llm-docs/embeddings/index.md
llm-docs/index.md
llm-docs/logging.md
llm-docs/plugins/directory.md
llm-docs/plugins/index.md

文件假定为utf-8,但如果遇到编码错误,LLM将回退到latin-1。您可以使用--encoding选项指定不同的编码集。

这个例子将首先尝试utf-16,然后尝试mac_roman,最后回退到latin-1

llm embed-multi documentation \
  -m 3-small \
  --files docs '**/*.md' \
  -d documentation.db \
  --encoding utf-16 \
  --encoding mac_roman \
  --encoding latin-1

如果无法读取文件,将会记录到标准错误,但脚本将继续运行。

如果您正在嵌入二进制内容(例如与CLIP一起使用的图像),请添加--binary选项:

llm embed-multi photos \
  -m clip \
  --files photos/ '*.jpeg' --binary

llm 相似#

llm similar 命令在嵌入集合中搜索与给定项目或项目ID最相似的项目。

目前使用的是较慢的暴力方法,这种方法在处理大规模集合时表现不佳。有关通过插件提供的向量索引添加更具扩展性方法的计划,请参见issue 216

要在quotations集合中搜索与'computer science'语义相似的项目:

llm similar quotations -c 'computer science'

这将嵌入提供的字符串并返回一个以换行符分隔的JSON对象列表,如下所示:

{"id": "philkarlton-1", "score": 0.8323904531677017, "content": null, "metadata": null}

你可以使用-i filename来与存储在文件中的文本进行比较:

llm similar quotations -i one.txt

或者使用-i -将文本输入到标准输入中:

echo 'computer science' | llm similar quotations -i -

当使用像CLIP这样的模型时,你可以使用-i filename--binary来找到与输入图像相似的图像:

llm similar photos -i image.jpg --binary

llm 嵌入模型#

要列出所有可用的嵌入模型,包括插件提供的模型,请运行以下命令:

llm embed-models

输出应该看起来像这样:

OpenAIEmbeddingModel: text-embedding-ada-002 (aliases: ada, ada-002)
OpenAIEmbeddingModel: text-embedding-3-small (aliases: 3-small)
OpenAIEmbeddingModel: text-embedding-3-large (aliases: 3-large)
...

添加 -q 一次或多次以搜索匹配这些术语的模型:

llm embed-models -q 3-small

llm embed-models 默认#

此命令可用于获取和设置默认的嵌入模型。

这将返回当前默认模型的名称:

llm embed-models default

你可以像这样设置一个不同的默认值:

llm embed-models default 3-small

这将把默认模型设置为OpenAI的3-small模型。

可以将模型支持的任何别名传递给此命令。

你可以使用--remove-default来取消默认模型:

llm embed-models default --remove-default

当没有设置默认模型时,llm embedllm embed-multi 命令将需要使用 -m/--model 指定一个模型。

llm 集合列表#

要列出嵌入数据库中的所有集合,请运行以下命令:

llm collections list

添加 --json 以获取 JSON 输出:

llm collections list --json

添加 -d/--database 以指定不同的数据库文件:

llm collections list -d my-embeddings.db

llm collections 删除#

要从数据库中删除一个集合,请运行以下命令:

llm collections delete collection-name

传递 -d 以指定不同的数据库文件:

llm collections delete collection-name -d my-embeddings.db