sage-common: Foundation Layer (L1)¶
请求路径(Control Plane Only)¶
User Code ──► UnifiedInferenceClient.create()
│ control_plane_url / SAGE_UNIFIED_BASE_URL / Gateway 默认端口
▼
RequestClassifier
▼
HybridSchedulingPolicy ──► Embedding Batcher
│ │
│ └─► EmbeddingExecutor (batch to /v1/embeddings)
▼
ExecutionCoordinator (HttpExecutionCoordinator)
▼
Gateway/Control Plane → vLLM / TEI / Embedding instances (SagePorts.*)
- 唯一入口:
UnifiedInferenceClient.create()(仅控制平面模式)。 - 默认基址:
control_plane_url参数 >SAGE_UNIFIED_BASE_URL>http://localhost:{SagePorts.GATEWAY_DEFAULT}/v1。 - 端口常量来自
SagePorts,禁止硬编码。
示例(控制平面)¶
from sage.llm import UnifiedInferenceClient
# 默认:使用本地 Gateway 端口(SagePorts.GATEWAY_DEFAULT)
client = UnifiedInferenceClient.create()
# 显式指定 Control Plane / Gateway
client = UnifiedInferenceClient.create(control_plane_url="http://localhost:8889/v1")
# 按模型名绑定(仍经由 Control Plane)
model_bound = UnifiedInferenceClient.create_for_model("Qwen/Qwen2.5-7B-Instruct")
resp = client.chat([{ "role": "user", "content": "写一份日报" }])
│ ExecutionCoord │ EmbeddingExecutor │ Metrics / Autos │ ├───────────────┴──────────────┬──────────────┴──────────────┬───┤ │ GPUResourceManager │ EngineLifecycleManager │ │ ├──────────────────────────────┴──────────────────────────────┴───┤ │ vLLM / TEI / Embedding instances (SagePorts.*) │ └─────────────────────────────────────────────────────────────────┘
- `control_plane/manager.py`:路由 + 负载均衡 + Autoscaler;与 GPU/引擎管理器协作。
- `strategies/hybrid_policy.py`:LLM/Embedding 混合批调度。
- `executors/http_client.py` & `embedding_executor.py`:对接 OpenAI 兼容后端。
- `metrics_collector.py`:SLA/P95 监控,可驱动 `SLOAwarePolicy`。
### Embedding 服务 (sage_embedding)
多种 Embedding 方法的统一接口:
```python
from sage.common.components.sage_embedding import (
EmbeddingFactory,
EmbeddingClientAdapter,
)
# EmbeddingFactory 返回单文本接口 → 通过 Adapter 获得批量 embed(list[str])
raw_embedder = EmbeddingFactory.create("hf", model="BAAI/bge-small-zh-v1.5")
client = EmbeddingClientAdapter(raw_embedder)
vectors = client.embed(["Hello", "World"])
# 直接消费 BaseEmbedding 时需逐条调用:raw_embedder.embed("only-one-text")
支持的方法: hash, hf, openai, jina, zhipu, cohere, ollama, siliconcloud, bedrock,
nvidia_openai
端口配置 (SagePorts)¶
统一的端口管理,避免硬编码:
from sage.common.config.ports import SagePorts
# 统一端口常量(不要硬编码)
PORT_MAP = {
"Gateway": (SagePorts.GATEWAY_DEFAULT, "OpenAI 兼容 API"),
"LLM": (SagePorts.LLM_DEFAULT, "主推理服务"),
"Embedding": (SagePorts.EMBEDDING_DEFAULT, "Embedding Server"),
"Benchmark": (SagePorts.BENCHMARK_LLM, "WSL2 fallback / benchmark"),
}
recommended = SagePorts.get_recommended_llm_port()
print(f"LLM 在此机器使用端口: {recommended}")
if SagePorts.is_wsl():
# 8001 在 WSL2 可能出现监听但拒绝连接 → 回退 8901
recommended = SagePorts.LLM_WSL_FALLBACK
Data Types¶
- BaseDocument: Foundation for all document types
- Vector Types: Dense and sparse vector representations
- Metadata: Document metadata management
Utilities¶
- Logger: Structured logging system
- Config: Configuration management
- Exceptions: Custom exception hierarchy
Core Interfaces¶
- Common protocols and abstract base classes
- Serialization/deserialization interfaces
- Type definitions and validators
Architecture¶
sage-common/
├── components/
│ └── sage_embedding/ # Embedding 统一接口
│ ├── factory.py # EmbeddingFactory
│ ├── protocols.py # EmbeddingProtocol
│ └── ...
├── config/
│ └── ports.py # SagePorts 端口配置
├── types/ # Data type definitions
├── utils/ # Utility functions
└── exceptions/ # Exception classes
# LLM 控制面与统一客户端已迁移至 packages/sage-llm-core/src/sage/llm/
sageLLM Control Plane¶
高级调度系统,支持 LLM + Embedding 混合工作负载:
┌────────────────────────────────────────────────────────────────────────────┐
│ UnifiedInferenceClient │
│ create() / create(control_plane_url=...) │
├──────────────────────────────┬──────────────────────────────────────────────┤
│ RequestClassifier │ 分类: LLM_CHAT / LLM_GENERATE / EMBEDDING │
├──────────────────────────────┼──────────────────────────────────────────────┤
│ HybridSchedulingPolicy │ 批量 Embedding + SLO_Aware/FIFO/Fair 选路 │
├───────────────────────┬──────┴──────────────┬──────────────────────────────┤
│ ExecutionCoordinator │ EmbeddingExecutor │ Metrics/Autoscaler/PD Routing │
├───────────────────────┴────────────────────┴──────────────────────────────┤
│ vLLM / TEI / Embedding instances (SagePorts.*) │
└────────────────────────────────────────────────────────────────────────────┘
control_plane/manager.py:路由 + 负载均衡 + Autoscalerstrategies/hybrid_policy.py:LLM/Embedding 混合批调度 (sage.llm.control_plane.strategies.hybrid_policy)executors/http_client.py&embedding_executor.py:对接 OpenAI 兼容后端metrics_collector.py:SLA/P95 监控,可驱动SLOAwarePolicy
动态引擎管理¶
Control Plane 支持运行时启动/停止推理引擎,并自动追踪 GPU 显存:
| 组件 | 说明 |
|---|---|
GPUResourceManager |
通过 NVML 监控 GPU 状态,维护逻辑预留账本 |
EngineLifecycleManager |
管理 vLLM / Embedding Server 进程生命周期 |
| Management API | /v1/management/engines (POST/DELETE) 与 /v1/management/status |
CLI 命令:
# 列出引擎
sage llm engine list
# 启动 LLM 引擎
sage llm engine start Qwen/Qwen2.5-7B-Instruct --tensor-parallel 2
# 启动 Embedding 引擎
sage llm engine start BAAI/bge-m3 --engine-kind embedding
# 停止引擎
sage llm engine stop <engine_id>
# 查看 GPU 状态
sage llm gpu
预设编排¶
使用预设一键部署多个引擎:
# 列出内置预设
sage llm preset list
# 查看预设详情
sage llm preset show -n qwen-mini-with-embeddings
# 应用预设
sage llm preset apply -n qwen-mini-with-embeddings
预设 YAML 示例:
version: 1
name: qwen-mini-with-embeddings
engines:
- name: chat
kind: llm
model: Qwen/Qwen2.5-1.5B-Instruct
- name: embed
kind: embedding
model: BAAI/bge-small-zh-v1.5
feature/control-plane-enhancement
Usage Examples¶
统一推理客户端¶
from sage.llm import UnifiedInferenceClient
from sage.common.config.ports import SagePorts
# 推荐:自动检测(Control Plane First)
client = UnifiedInferenceClient.create()
# 显式连接本地 Gateway(如 UnifiedAPIServer)
gateway = UnifiedInferenceClient.create(control_plane_url=f"http://localhost:{SagePorts.GATEWAY_DEFAULT}/v1")
# 内嵌模式适合批处理脚本
embedded = "(deprecated)"
status = client.get_status()
print(f"LLM available: {status['llm_available']}")
print(f"Embedding available: {status['embedding_available']}")
本地 Embedding¶
from sage.common.components.sage_embedding import (
EmbeddingFactory,
EmbeddingClientAdapter,
list_embedding_models,
)
for method, info in list_embedding_models().items():
print(f"{method}: {info['description']}")
embedder = EmbeddingFactory.create("hash", dim=384)
client = EmbeddingClientAdapter(embedder) # 获得批量接口
vectors = client.embed(["Hello", "World"])
single_vector = embedder.embed("single-text") # 仍可按需单条调用
# 离线模式:配合 UnifiedInferenceClient 只负责 embedding,LLM 仍可走 Control Plane
环境变量示例¶
Control Plane 自动探测优先读取 SAGE_* 前缀,随后才会尝试本地端口与云 API:
# .env(示例,数值来自 SagePorts 常量)
SAGE_CHAT_BASE_URL=http://localhost:8901/v1 # SagePorts.get_recommended_llm_port()
SAGE_CHAT_MODEL=Qwen/Qwen2.5-7B-Instruct
SAGE_CHAT_API_KEY=token-optional
SAGE_EMBEDDING_BASE_URL=http://localhost:8090/v1 # SagePorts.EMBEDDING_DEFAULT
SAGE_EMBEDDING_MODEL=BAAI/bge-m3
HF_TOKEN=hf_xxx
# detect_china_mainland() 会在 CLI 中自动调用 ensure_hf_mirror_configured()
# 如果在中国大陆,可提前设置:
HF_ENDPOINT=https://hf-mirror.com
CLI 入口如
sage llm serve和sage llm model download均会调用sage.common.config.network.ensure_hf_mirror_configured(),自动根据detect_china_mainland()调整HF_ENDPOINT。
端口 & WSL2 指南¶
from sage.common.config.ports import SagePorts
if SagePorts.is_wsl():
llm_port = SagePorts.LLM_WSL_FALLBACK # 8901
else:
llm_port = SagePorts.LLM_DEFAULT # 8001
print("启动命令:", f"sage llm serve --port {llm_port} --embedding-port {SagePorts.EMBEDDING_DEFAULT}")
UnifiedInferenceClient.create()仅使用 Control Plane/Gateway 端口(默认SagePorts.GATEWAY_DEFAULT),不再扫描本地 vLLM 端口。SagePorts.is_available(port)可在脚本内检测端口是否被占用。sage llm serve --port <LLM_PORT> --embedding-port <EMBED_PORT>会自动写入.sage/llm/daemon.json,供 CLI 与 Control Plane 共享。
服务启动示例¶
# recommended: 通过 CLI 在 SagePorts 上启动服务栈
sage llm serve \
--model Qwen/Qwen2.5-7B-Instruct \
--embedding-model BAAI/bge-m3 \
--port $(python -c "from sage.common.config.ports import SagePorts; print(SagePorts.get_recommended_llm_port())") \
--embedding-port 8090 # SagePorts.EMBEDDING_DEFAULT
# 无需 Embedding 时:
sage llm serve --no-embedding
# 查看状态/日志
sage llm status && sage llm logs --tail 100
Dependencies¶
- External:
openai,httpx,torch(optional for HF models) - Internal: None (foundation layer)
Environment Variables(本地优先)¶
参考 .env.template:
# Chat / LLM(显式指定或使用本地端口探测)
SAGE_CHAT_API_KEY=sk-your-key
SAGE_CHAT_MODEL=Qwen/Qwen2.5-7B-Instruct
SAGE_CHAT_BASE_URL=http://localhost:8001/v1 # SagePorts.LLM_DEFAULT;WSL2 可用 8901
# Embedding(显式指定或使用本地端口探测)
SAGE_EMBEDDING_BASE_URL=http://localhost:8090/v1 # SagePorts.EMBEDDING_DEFAULT
SAGE_EMBEDDING_MODEL=BAAI/bge-m3
# 本地端口(CLI 会写入)
SAGE_LLM_PORT=8001 # SagePorts.LLM_DEFAULT(WSL2 可改为 8901)
SAGE_EMBEDDING_PORT=8090
# HF 下载
HF_TOKEN=hf_xxx
# CLI 入口会调用 ensure_hf_mirror_configured() 自动判断是否需要 HF_ENDPOINT
See Also¶
- Embedding 模块 - 详细的 Embedding 用法
- 部署指南 - LLM/Embedding 服务部署
- Architecture Overview
- Package Structure
网络/镜像:参见
sage.common.config.network中的detect_china_mainland()、ensure_hf_mirror_configured()。