MemOS 模型后端配置指南:LLM 与 Embedder 工厂的架构、参数与实战

原创2026-09-24 02:24:5118 阅读
文章标签:人工智能大模型Agent 记忆AI AgentRAG知识图谱dsh-plugin

MemOS 模型后端配置指南:LLM 与 Embedder 工厂的架构、参数与实战

导读

本文基于 MemOS 官方模块文档 model_backend.md 展开,系统讲解 MemOS 如何通过 LLMFactoryEmbedderFactory 两个 Pydantic 工厂类,将模型逻辑运行时配置彻底解耦:只需一次 backend= 切换,即可在同一套 API 下接入 Ollama、OpenAI、Azure、Qwen、DeepSeek、HuggingFace、vLLM 等对话模型,以及 Ollama、sentence-transformers、火山引擎 Ark、通用 OpenAI 兼容接口等嵌入模型。读完本文,你将掌握两种工厂的完整配置模式、全部后端参数与默认值、流式输出与思维链(CoT)处理,并能直接复用仓库中开箱即用的 8 个 LLM 场景与 5 个嵌入器场景示例。

概述:双工厂架构如何解耦模型与配置

MemOS 将模型逻辑运行时配置分离为两个正交维度,由两个 Pydantic 工厂统一管理:

工厂类 产出 典型后端
LLMFactory 对话模型 ollama, openai, azure, qwen, deepseek, huggingface, huggingface_singleton, vllm, openai_new
EmbedderFactory 文本嵌入器 ollama, sentence_transformer, ark, universal_api

两个工厂均接受 *_ConfigFactory.model_validate(...) 生成的配置对象,因此切换服务提供商只需修改 backend= 一个字段。从源码结构看,这一设计的核心是双层映射

  • 配置层:LLMConfigFactory.backend_to_class 将后端名映射到具体 Pydantic 配置类(见 src/memos/configs/llm.py),并在 model_validator 阶段把传入的 config 字典实例化为对应配置对象;
  • 实现层:LLMFactory.backend_to_class 将同一后端名映射到具体的模型实现类(见 src/memos/llms/factory.py)。

这意味着"换后端"只是换两个映射表里的键,上层调用方永远面对统一的 generate / generate_stream / embed 接口,这一模式与 MemOS 中 Chunker、VecDB 等模块的工厂设计保持一致。

LLM 模块

支持的 LLM 后端

Backend 说明 示例 model_name_or_path
ollama 本地 Ollama 服务器 qwen3:0.6b
openai 兼容 OpenAI 的 Chat Completions 接口 gpt-4.1-nano
azure Azure OpenAI Chat Completions <your-deployment-name>
qwen DashScope 兼容 OpenAI 的 API qwen-plus
deepseek DeepSeek 兼容 OpenAI 的 API deepseek-chat / deepseek-reasoner
huggingface 本地 transformers pipeline Qwen/Qwen3-1.7B
huggingface_singleton huggingface 相同,但启用单例复用 Qwen/Qwen3-1.7B
vllm 兼容 OpenAI 的 vLLM 服务器 Qwen/Qwen2.5-7B-Instruct
openai_new OpenAI Responses API 封装 gpt-4.1

需要补充的是,从 src/memos/llms/factory.pysrc/memos/configs/llm.py 的源码映射可以看出,当前仓库实际还内置了第 10 个后端 minimax(对应 MinimaxLLMConfig / MinimaxLLM,官方示例中可用模型包括 MiniMax-M2.7 等),原文档表格未列出,但同样可以通过 backend="minimax" 直接启用。

LLM 配置模式

所有 LLM 后端共享 BaseLLMConfig 中的通用字段(定义见 src/memos/configs/llm.py):

字段 类型 默认值 描述
model_name_or_path str –(必填) 模型 ID 或本地标签
temperature float 0.7 采样温度
max_tokens int 8192 最大生成 token 数
top_p / top_k float / int 0.95 / 50 采样裁剪参数
API 专用字段 api_keyapi_base OpenAI 兼容的认证信息
remove_think_prefix bool False 从生成文本中移除思考标签(<think>...</think>)内的内容
default_headers dict | None None 请求默认 HTTP 头(源码级补充字段)

各后端的 API 专用字段 差异集中在 api_base / api_key 的默认值与认证方式上,以下是源码中确认的默认端点(src/memos/configs/llm.py):

  • openaiapi_base 默认 https://api.openai.com/v1,需要 api_key;支持 enable_thinking(默认 None,即保留提供商默认行为)、extra_body,还支持 backup_client 一键开启主备双通道容灾(backup_api_keybackup_api_basebackup_model_name_or_pathbackup_headers);
  • azure:字段名为 base_url(默认 https://api.openai.azure.com/)+ api_version(默认 2024-03-01-preview)+ api_key,模型名对应 Azure 上的部署名;
  • qwen:继承 OpenAI 配置,api_base 默认 https://dashscope-intl.aliyuncs.com/compatible-mode/v1
  • deepseek:继承 OpenAI 配置,api_base 默认 https://api.deepseek.com
  • ollamaapi_base 默认 http://localhost:11434enable_thinking 默认 False;
  • vllmapi_key 默认为空串(本地服务可省略),api_base 默认 http://localhost:8088/v1enable_thinking 默认 False;
  • huggingface / huggingface_singleton:额外提供 do_sample(默认 False,即贪心解码)与 add_generation_prompt(默认 True,自动套用对话生成模板);
  • openai_new:封装 OpenAI Responses API,enable_thinking 默认 False。

工厂用法

from memos.configs.llm import LLMConfigFactory
from memos.llms.factory import LLMFactory

cfg = LLMConfigFactory.model_validate({
    "backend": "ollama",
    "config": {"model_name_or_path": "qwen3:0.6b"}
})
llm = LLMFactory.from_config(cfg)

这里的 LLMConfigFactory.model_validate 会先校验 backend 合法性(不在映射表中的后端名直接抛 ValueError: Invalid backend),随后通过 model_validator(mode="after")config 字典自动实例化为对应后端配置类(见 src/memos/configs/llm.py),因此工厂拿到的始终是类型完备的强类型配置,而不是裸字典。

LLM 核心 API

所有后端实现均继承自抽象基类 BaseLLM(见 src/memos/llms/base.py),对外只暴露两个核心方法:

方法 用途
generate(messages: list) 返回完整的字符串响应
generate_stream(messages) 以流式方式逐块生成内容

值得注意的是,LLMFactory.from_config@singleton_factory() 装饰(见 src/memos/llms/factory.py),即同一配置下创建的 LLM 实例会被单例化复用,避免重复初始化客户端连接——这也是 huggingface_singleton 后端在加载本地大模型场景下的关键价值。

流式输出与思维链(CoT)

messages = [{"role": "user", "content": "Let's think step by step: …"}]
for chunk in llm.generate_stream(messages):
    print(chunk, end="")

对于 Qwen、DeepSeek 这类会返回 reasoning_content(推理内容)的模型,OpenAILLMAzureLLM 的流式实现会自动把推理过程包装成 <think>...</think> 块再按序输出(见 src/memos/llms/openai.py):推理内容先于正文输出,并保证 </think> 正确闭合。Ollama 后端同样支持 thinking 字段的流式透传(见 src/memos/llms/ollama.py)。如果希望最终结果不含思考过程,只需设置 remove_think_prefix: true,工厂内部会调用 remove_thinking_tags 剥离思考标签内容。

完整代码 全部 8 个场景示例请参见 examples/basic_modules/llm.py,覆盖:Ollama 工厂用法、Pydantic 直接实例化、OpenAI(含流式)、HuggingFace 本地模型、Qwen(DashScope)、DeepSeek-chat、MiniMax、DeepSeek-reasoner 推理 + CoT 流式。

性能建议

  • 在本地原型开发时,使用 qwen3:0.6b 可将内存占用控制在 2 GB 以内,配合 Ollama 本地服务即可完成全流程验证;
  • 结合 KV Cache(详见 KVCacheMemory 文档)可降低首个 token 的生成延迟(TTFT):MemOS 的 MemScheduler 会把语义稳定、高频复用的背景知识预计算为 KVCacheItem(Key/Value 张量),推理时直接注入注意力缓存,避免对未变化的记忆内容重复编码,从而显著压缩 prefill 阶段开销。

嵌入模块

支持的嵌入器后端

Backend 说明 示例 model_name_or_path
ollama 本地 Ollama 服务器 nomic-embed-text:latest
sentence_transformer 本地 sentence-transformers nomic-ai/nomic-embed-text-v1.5
ark 火山引擎 Ark 嵌入服务 <ark-model-id>
universal_api 通用服务提供商封装(如 OpenAI、Azure) text-embedding-3-large

嵌入器配置模式

所有嵌入器共享 BaseEmbedderConfig(见 src/memos/configs/embedder.py)中的公共字段:

字段 类型 默认值 描述
model_name_or_path str –(必填) 模型 ID 或本地标签
embedding_dims int | None None 嵌入向量维度
max_tokens int | None 8192 单条文本最大 token 数,超限自动截断;设为 None 可关闭截断
headers_extra dict | None None 额外请求头,仅 universal_api 后端使用

后端专属字段:

  • ollamaapi_base 默认 http://localhost:11434
  • ark:必填 api_keyapi_base 默认 https://ark.cn-beijing.volces.com/api/v3/,另有 chunk_size(默认 1)与 multi_modal(默认 False,是否启用文本 + 图像多模态嵌入);
  • sentence_transformertrust_remote_code 默认 True,允许加载依赖远程代码的 HF 模型;
  • universal_api:必填 provider(如 openai)与 api_key,可选 base_url 指向自定义或代理端点;同样支持 backup_client 及配套的 backup_base_urlbackup_api_keybackup_model_name_or_pathbackup_headers_extra 主备容灾配置。

工厂用法

from memos.configs.embedder import EmbedderConfigFactory
from memos.embedders.factory import EmbedderFactory

cfg = EmbedderConfigFactory.model_validate({
    "backend": "ollama",
    "config": {"model_name_or_path": "nomic-embed-text:latest"}
})
embedder = EmbedderFactory.from_config(cfg)

src/memos/embedders/factory.py 可以看到两个额外的实现细节:

  1. 与 LLM 工厂一样,from_config 也被 @singleton_factory() 装饰,同一配置的嵌入器实例全局复用;
  2. EmbedderFactory.cacheable_backends = {"ollama", "ark", "universal_api"}——当嵌入优化开关 embedding_optimization_enabled() 打开时,这三个后端的实例会被自动包装为 CachingEmbedder,对相同文本命中向量缓存,避免重复调用昂贵的嵌入 API(sentence_transformer 是本地模型,不在缓存列表中)。

嵌入调用与文本截断

所有嵌入器实现 embed(texts: list<a href="https://link.gitcode.com/i/132392556ba5132622fea03781518eab" target="_blank">str]) -> list[list[float]] 接口。BaseEmbedder 内置了 token 级截断保护(见 [src/memos/embedders/base.py):优先使用 tiktoken(gpt-4o-mini 编码,失败回退 cl100k_base)统计 token 数,超过 max_tokens 的文本通过二分搜索定位最优截断点;未安装 tiktoken 时退化为启发式估算(中文字符约 1 token/字,其余字符约 4 字符/token)。此外每次嵌入调用都会由 log_embedding_call 装饰器记录模型、批次大小、字符数、耗时与状态等观测指标,便于排查嵌入链路性能问题。

实战:从示例到真实配置

LLM 全场景速查

仓库 examples/basic_modules/llm.py 提供了可直接运行的 8 个场景,以下是两个最具代表性的完整配置:

本地 Ollama(推荐原型方案)

config = LLMConfigFactory.model_validate({
    "backend": "ollama",
    "config": {
        "model_name_or_path": "qwen3:0.6b",
        "temperature": 0.8,
        "max_tokens": 1024,
        "top_p": 0.9,
        "top_k": 50,
    },
})
llm = LLMFactory.from_config(config)
response = llm.generate([{"role": "user", "content": "How are you? /no_think"}])

需要注意 Ollama 后端在初始化时会自动检查本地模型是否存在,缺失则调用 client.pull(...) 拉取(见 src/memos/llms/ollama.py);若未指定模型名,默认回退到 llama3.1:latest

DeepSeek 推理 + 思维链流式

cfg2 = LLMConfigFactory.model_validate({
    "backend": "deepseek",
    "config": {
        "model_name_or_path": "deepseek-reasoner",
        "api_key": "sk-xxx",
        "api_base": "https://api.deepseek.com",
        "temperature": 0.2,
        "max_tokens": 1024,
        "remove_think_prefix": False,
    },
})
llm = LLMFactory.from_config(cfg2)
for chunk in llm.generate_stream([
    {"role": "user", "content": "Explain step-by-step. "
     "If a train travels A→B at 60 mph and returns at 40 mph, "
     "what is the average speed? Let's think step by step."}
]):
    print(chunk, end="")

其余场景(OpenAI、HuggingFace、Qwen、MiniMax 等)的完整代码同样在该文件中,api_key 一律建议通过环境变量注入,切勿硬编码提交到版本库。

嵌入器全场景速查

仓库 examples/basic_modules/embedder.py 提供 5 个场景,核心用法如下:

# Ollama 本地嵌入(需先 ollama pull nomic-embed-text)
config = EmbedderConfigFactory.model_validate({
    "backend": "ollama",
    "config": {"model_name_or_path": "nomic-embed-text:latest"},
})
embedder = EmbedderFactory.from_config(config)
embedding = embedder.embed(["This is a sample text for embedding generation."])
print("embedding shape:", len(embedding[0]))

# Universal API 包装 OpenAI(可换成任意兼容端点)
config_api = EmbedderConfigFactory.model_validate({
    "backend": "universal_api",
    "config": {
        "provider": "openai",
        "api_key": "<YOUR_KEY>",
        "model_name_or_path": "text-embedding-3-large",
        "base_url": "https://api.myproxy.com/v1",
    },
})
embedder_api = EmbedderFactory.from_config(config_api)

该文件还演示了批量嵌入(一次传入多段文本)、sentence_transformer 本地模型(首次运行会自动从 HuggingFace 下载)以及 universal_api 对接 Azure 的写法。使用 sentence_transformer 时需确保安装 einops(部分 HF 模型如 nomic-bert 依赖它)。

在 MemOS 配置文件中落地

模型后端不仅可以在 Python 代码中以工厂方式使用,也是 MemOS 顶层配置的组成部分。参考调度器配置示例 memos_config_w_scheduler.yamlchat_modelmem_reader 内的 llm / embedder 均使用相同的 backend + config 双层结构:

user_id: "root"
chat_model:
  backend: "huggingface_singleton"
  config:
    model_name_or_path: "Qwen/Qwen3-1.7B"
    temperature: 0.1
    remove_think_prefix: true
    max_tokens: 4096
mem_reader:
  backend: "simple_struct"
  config:
    llm:
      backend: "huggingface_singleton"
      config:
        model_name_or_path: "Qwen/Qwen3-1.7B"
        temperature: 0.1
        remove_think_prefix: true
        max_tokens: 4096
    embedder:
      backend: "ollama"
      config:
        model_name_or_path: "nomic-embed-text:latest"
    chunker:
      backend: "sentence"
      config:
        tokenizer_or_token_counter: "gpt2"
        chunk_size: 512
        chunk_overlap: 128

这种"一次定义、全链路复用"的配置方式,正是双工厂解耦设计在生产部署中的直接体现:chat_model 决定对话生成所用的 LLM,mem_reader.llm 决定文档结构化抽取所用的 LLM,mem_reader.embedder 决定向量化所用的嵌入器,三者可各自独立切换后端而互不影响。

源码级验证与测试

总结

MemOS 的模型后端体系用一个统一的双工厂模式,把"选择模型提供商"从业务代码中彻底剥离:backend 字段是唯一需要修改的开关,其余全部由 Pydantic 配置类完成强类型校验与默认值管理。无论是本地 2 GB 以内的 Ollama 快速原型(qwen3:0.6b + nomic-embed-text)、需要可控推理的 DeepSeek 思维链场景,还是面向生产的主备容灾(backup_client)与嵌入向量缓存(CachingEmbedder),都可以在本文所述配置模式内直接落地。建议进一步阅读 KVCacheMemory 文档 了解 TTFT 优化,并结合 examples/basic_modules/llm.pyexamples/basic_modules/embedder.py 实际运行验证。

登录后查看全文
MemOS