初始提交:边缘AI算力机统一AI通讯层
This commit is contained in:
@@ -0,0 +1,973 @@
|
||||
# 边缘 AI 算力机统一 AI 通讯层设计方案
|
||||
|
||||
> 文档定位:用于边缘 AI 算力机的软件架构设计、产品立项、技术评审与研发实施。
|
||||
>
|
||||
> 核心目标:在业务应用和底层 AI 模型之间建设统一的 AI 通讯与调度层,对每一次 AI 调用进行标准化接入、上下文控制、排队调度、连接管理、资源治理和运行监控。
|
||||
|
||||
---
|
||||
|
||||
## 1. 建设背景
|
||||
|
||||
边缘 AI 算力机通常同时运行大语言模型、视觉模型、语音模型、Embedding 模型以及重排序模型。随着接入应用数量增加,如果各业务应用直接调用 Ollama、vLLM、llama.cpp、TensorRT-LLM、Triton 或其他推理服务,将逐渐出现以下问题:
|
||||
|
||||
- 不同应用使用不同的调用协议,接入成本和维护成本持续增加;
|
||||
- 应用各自保存会话历史,缺少统一的上下文长度、Token 和敏感信息控制;
|
||||
- 多个请求同时进入模型服务,容易导致显存不足、推理进程崩溃或延迟突然升高;
|
||||
- 缺少统一排队机制,高优先级实时任务可能被后台批处理任务阻塞;
|
||||
- HTTP 连接断开后,模型仍可能继续生成,造成 GPU 算力和显存浪费;
|
||||
- 不同应用各自设置超时、重试和降级策略,容易出现重复调用和调用风暴;
|
||||
- 无法统一统计模型吞吐量、首 Token 延迟、Token 消耗、排队时长和失败原因;
|
||||
- 本地算力不足时,缺少受控的小模型降级、备用设备切换或云端模型路由机制;
|
||||
- 应用与具体模型实现强耦合,模型升级、迁移或替换会影响所有业务系统。
|
||||
|
||||
因此,需要在应用与推理服务之间建设统一的 **AI 通讯层(Edge AI Gateway)**。所有 AI 请求都通过该层进入算力机,由它统一决定请求能否执行、何时执行、使用哪个模型、携带多少上下文、占用多少资源以及何时终止。
|
||||
|
||||
---
|
||||
|
||||
## 2. 建设目标
|
||||
|
||||
统一 AI 通讯层应实现以下目标:
|
||||
|
||||
1. **统一接入**:向业务应用提供稳定、标准、版本化的 AI API。
|
||||
2. **统一上下文**:集中管理会话、历史消息、系统提示词、知识检索结果和 Token 预算。
|
||||
3. **统一调度**:根据优先级、租户配额、模型能力和设备资源进行排队与执行。
|
||||
4. **统一连接控制**:管理连接建立、排队等待、首 Token、推理、空闲和总调用时间。
|
||||
5. **统一模型路由**:屏蔽 Ollama、vLLM、TensorRT-LLM、Triton 和云端模型接口差异。
|
||||
6. **统一资源治理**:控制 GPU/NPU/CPU、显存、KV Cache、模型驻留和并发执行槽位。
|
||||
7. **统一可靠性机制**:提供限流、背压、取消、熔断、幂等、重试和降级能力。
|
||||
8. **统一可观测性**:记录调用链、排队时间、推理耗时、Token 用量、资源使用和错误原因。
|
||||
9. **统一安全策略**:实现应用认证、租户隔离、权限管理、审计、脱敏和数据留存控制。
|
||||
10. **降低业务耦合**:业务应用只描述任务需求,不直接依赖模型部署方式。
|
||||
|
||||
---
|
||||
|
||||
## 3. 设计原则
|
||||
|
||||
### 3.1 通讯层是控制面,不是简单反向代理
|
||||
|
||||
普通反向代理主要负责转发、负载均衡和连接复用,而 AI 通讯层还必须理解模型、Token、上下文窗口、显存、生成状态和流式响应。因此,它需要具备请求准入、上下文编排、模型路由和推理任务生命周期管理能力。
|
||||
|
||||
### 3.2 会话数据与实际模型上下文分离
|
||||
|
||||
会话可以保存完整历史,但每次发送给模型的上下文必须根据模型窗口、输出预算和任务相关性重新组装,不能无上限地追加历史记录。
|
||||
|
||||
### 3.3 先准入、后排队、再执行
|
||||
|
||||
每个请求进入系统后,必须先完成身份、配额、参数、Token 预算和资源风险检查。无法安全执行的请求应在进入模型前被拒绝或降级。
|
||||
|
||||
### 3.4 连接中断必须传播为推理取消
|
||||
|
||||
客户端断开、主动取消或总超时后,通讯层必须将取消信号传递到模型适配器,并释放执行槽位、KV Cache 和其他临时资源。
|
||||
|
||||
### 3.5 边缘优先,云端受控
|
||||
|
||||
敏感任务默认在本地执行。只有明确允许云端处理的数据,才可以在本地过载或模型能力不足时路由到云端,并形成完整审计记录。
|
||||
|
||||
### 3.6 单机先行,保留集群扩展能力
|
||||
|
||||
第一阶段不应为了未来可能出现的规模而引入过多分布式组件。单机部署可采用进程内队列和轻量状态存储,但任务、模型和节点接口需要为多机调度预留扩展空间。
|
||||
|
||||
---
|
||||
|
||||
## 4. 总体架构
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["业务应用 / Agent / 智能终端"] --> B["统一 AI 通讯层"]
|
||||
|
||||
subgraph G["AI 通讯层"]
|
||||
B1["协议适配与 API 网关"]
|
||||
B2["认证、配额与限流"]
|
||||
B3["会话与上下文管理"]
|
||||
B4["任务队列与调度器"]
|
||||
B5["模型路由器"]
|
||||
B6["连接与生命周期管理"]
|
||||
B7["资源管理器"]
|
||||
B8["可观测与审计"]
|
||||
end
|
||||
|
||||
B --> B1 --> B2 --> B3 --> B4 --> B5 --> B6
|
||||
B4 <--> B7
|
||||
B6 --> C1["LLM 推理服务"]
|
||||
B6 --> C2["视觉模型服务"]
|
||||
B6 --> C3["语音模型服务"]
|
||||
B6 --> C4["Embedding / Rerank"]
|
||||
B6 --> C5["备用边缘节点或云端模型"]
|
||||
|
||||
B3 <--> D1["会话与记忆存储"]
|
||||
B4 <--> D2["任务状态与队列存储"]
|
||||
B8 --> D3["指标、日志与调用链"]
|
||||
```
|
||||
|
||||
### 4.1 核心模块职责
|
||||
|
||||
| 模块 | 主要职责 |
|
||||
|---|---|
|
||||
| 协议适配与 API 网关 | 提供 HTTP、SSE、WebSocket、gRPC 等接口,统一请求和响应格式 |
|
||||
| 认证与配额 | API Key、JWT、应用身份、租户权限、调用量和并发配额 |
|
||||
| 会话管理 | 会话创建、消息存储、过期、删除、隔离和生命周期管理 |
|
||||
| 上下文编排 | 系统提示词、历史摘要、最近对话、知识检索和输出预算组装 |
|
||||
| 调度器 | 优先级、公平性、并发、队列超时、资源准入和任务分派 |
|
||||
| 模型路由器 | 根据能力、延迟、隐私、负载、成本和资源状态选择模型 |
|
||||
| 连接管理器 | 流式返回、心跳、断线检测、取消传播和分层超时 |
|
||||
| 资源管理器 | GPU/NPU、显存、执行槽位、模型驻留、KV Cache 和温度管理 |
|
||||
| 模型适配器 | 屏蔽不同推理引擎和云端模型的协议差异 |
|
||||
| 可观测模块 | 指标、日志、链路追踪、告警、审计与成本统计 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 标准调用流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant APP as 业务应用
|
||||
participant GW as AI 通讯层
|
||||
participant CTX as 上下文管理器
|
||||
participant SCH as 调度器
|
||||
participant RM as 资源管理器
|
||||
participant INF as 推理服务
|
||||
|
||||
APP->>GW: 提交 AI 请求
|
||||
GW->>GW: 鉴权、限流、参数校验、幂等检查
|
||||
GW->>CTX: 加载会话并构建上下文
|
||||
CTX-->>GW: 返回受控 Prompt 与 Token 预算
|
||||
GW->>SCH: 创建任务并进入优先级队列
|
||||
SCH->>RM: 检查模型、显存和执行槽位
|
||||
RM-->>SCH: 允许执行或建议降级
|
||||
SCH->>INF: 提交推理任务
|
||||
INF-->>GW: 流式 Token / 推理结果
|
||||
GW-->>APP: SSE、WebSocket 或同步响应
|
||||
GW->>GW: 记录指标、结果和审计信息
|
||||
GW->>RM: 释放执行槽位与临时资源
|
||||
```
|
||||
|
||||
完整处理步骤如下:
|
||||
|
||||
1. 接收请求并生成全局唯一 `request_id`。
|
||||
2. 校验应用身份、用户权限、模型权限和数据策略。
|
||||
3. 检查应用级、用户级和设备级限流规则。
|
||||
4. 根据 `idempotency_key` 判断是否为重复请求。
|
||||
5. 校验输入大小、参数范围、文件类型和风险内容。
|
||||
6. 加载会话信息,组装本次调用上下文。
|
||||
7. 计算输入 Token、预留输出 Token,并执行上下文裁剪或摘要。
|
||||
8. 根据请求优先级和配额放入对应队列。
|
||||
9. 检查队列等待时间、模型状态、显存和执行槽位。
|
||||
10. 调度器选择模型实例并提交任务。
|
||||
11. 将首 Token 和后续内容以流式或非流式方式返回客户端。
|
||||
12. 监听客户端断开、主动取消、超时和模型异常。
|
||||
13. 推理完成后保存结果、更新会话并释放资源。
|
||||
14. 记录调用链、Token 数、排队时间、推理耗时和最终状态。
|
||||
|
||||
---
|
||||
|
||||
## 6. 上下文控制设计
|
||||
|
||||
### 6.1 上下文组成
|
||||
|
||||
建议按照固定优先级组装模型上下文:
|
||||
|
||||
1. 平台级安全规则;
|
||||
2. 应用级系统提示词;
|
||||
3. 当前用户身份、角色和权限;
|
||||
4. 会话长期摘要;
|
||||
5. 最近若干轮原始对话;
|
||||
6. 知识库检索结果;
|
||||
7. 工具调用结果;
|
||||
8. 当前用户请求;
|
||||
9. 输出格式和输出长度约束。
|
||||
|
||||
不同来源的上下文必须带有来源、时间、可信度、权限级别和 Token 数等元数据,便于裁剪、审计和问题追踪。
|
||||
|
||||
### 6.2 Token 预算
|
||||
|
||||
每次调用都应预先计算 Token 预算。例如模型上下文窗口为 32,000 Token:
|
||||
|
||||
| 上下文部分 | 预算 |
|
||||
|---|---:|
|
||||
| 平台与应用系统指令 | 2,000 |
|
||||
| 会话摘要 | 4,000 |
|
||||
| 最近对话 | 9,000 |
|
||||
| 知识检索结果 | 8,000 |
|
||||
| 当前请求与工具结果 | 3,000 |
|
||||
| 模型输出预留 | 6,000 |
|
||||
| 合计 | 32,000 |
|
||||
|
||||
预算应按模型单独配置,不能直接使用模型标称上限。为避免边界误差,建议保留 5%~10% 的安全空间。
|
||||
|
||||
### 6.3 上下文超限处理
|
||||
|
||||
超出预算时,按照以下顺序处理:
|
||||
|
||||
1. 删除重复或低相关度的知识片段;
|
||||
2. 压缩过长的工具返回结果;
|
||||
3. 删除最早且无关键状态的对话;
|
||||
4. 将较早对话转换为结构化摘要;
|
||||
5. 降低检索结果数量或单段长度;
|
||||
6. 在策略允许时切换到更大上下文模型;
|
||||
7. 仍无法满足时返回明确的上下文超限错误。
|
||||
|
||||
不能静默截断系统指令、权限信息、当前问题或输出约束。
|
||||
|
||||
### 6.4 会话与记忆
|
||||
|
||||
建议区分三类信息:
|
||||
|
||||
- **原始会话历史**:用于审计和重新生成,不一定每次进入模型;
|
||||
- **短期上下文**:最近若干轮对话,直接进入当前 Prompt;
|
||||
- **长期记忆**:经过提取和确认的用户偏好、业务状态或任务结论,按需检索。
|
||||
|
||||
会话需要支持以下策略:
|
||||
|
||||
- 最大生命周期和空闲过期时间;
|
||||
- 最大消息数和最大累计 Token 数;
|
||||
- 租户、应用和用户之间严格隔离;
|
||||
- 敏感字段脱敏或禁止持久化;
|
||||
- 用户主动清除会话和记忆;
|
||||
- 摘要模型、摘要版本和摘要时间记录;
|
||||
- KV Cache 的复用范围、有效期和释放条件。
|
||||
|
||||
### 6.5 Prompt 注入防护
|
||||
|
||||
从知识库、网页、文件和工具获得的内容应标记为“不可信数据”,与系统指令分区组织。通讯层还应:
|
||||
|
||||
- 限制外部内容覆盖系统规则;
|
||||
- 对工具调用参数执行结构化校验;
|
||||
- 对高风险工具增加权限确认;
|
||||
- 过滤密钥、内部提示词和其他租户数据;
|
||||
- 记录最终进入模型的上下文版本和哈希值。
|
||||
|
||||
---
|
||||
|
||||
## 7. 队列与调度机制
|
||||
|
||||
### 7.1 三级处理模型
|
||||
|
||||
建议采用以下三级机制:
|
||||
|
||||
1. **接入准入**:鉴权、配额、限流、输入和 Token 检查;
|
||||
2. **排队调度**:优先级、公平性、队列超时和模型选择;
|
||||
3. **执行控制**:模型并发、显存准入、批处理、取消和资源释放。
|
||||
|
||||
### 7.2 优先级设计
|
||||
|
||||
| 等级 | 任务示例 | 调度目标 |
|
||||
|---|---|---|
|
||||
| P0 | 安防告警、设备故障处置 | 立即执行,必要时预留专用资源 |
|
||||
| P1 | 实时语音、人机交互 | 低排队时间和低首 Token 延迟 |
|
||||
| P2 | 普通问答、办公助手 | 默认服务等级 |
|
||||
| P3 | 文档分析、报表生成 | 可容忍一定排队时间 |
|
||||
| P4 | 索引构建、离线摘要 | 仅在资源空闲时执行 |
|
||||
|
||||
不建议允许普通应用直接声明最高优先级。应用能够使用的优先级范围应由后台策略控制。
|
||||
|
||||
### 7.3 公平调度
|
||||
|
||||
单纯的优先级队列可能导致低优先级任务长期得不到执行。建议组合使用:
|
||||
|
||||
- 加权公平队列;
|
||||
- 租户或应用并发上限;
|
||||
- 用户并发上限;
|
||||
- 优先级老化,等待越久的任务逐步提升权重;
|
||||
- 长短任务分离;
|
||||
- 实时任务和批处理任务使用独立执行槽位;
|
||||
- 大上下文请求设置更高的资源权重。
|
||||
|
||||
### 7.4 并发与配额示例
|
||||
|
||||
```yaml
|
||||
global:
|
||||
max_running_tasks: 8
|
||||
max_queued_tasks: 500
|
||||
|
||||
applications:
|
||||
security_service:
|
||||
max_running_tasks: 4
|
||||
max_queued_tasks: 100
|
||||
allowed_priorities: [P0, P1]
|
||||
office_assistant:
|
||||
max_running_tasks: 2
|
||||
max_queued_tasks: 50
|
||||
allowed_priorities: [P2, P3]
|
||||
|
||||
users:
|
||||
default_max_running_tasks: 1
|
||||
default_requests_per_minute: 20
|
||||
```
|
||||
|
||||
### 7.5 显存准入
|
||||
|
||||
任务进入推理服务前,应估算以下资源:
|
||||
|
||||
- 模型权重占用;
|
||||
- 输入上下文对应的 KV Cache;
|
||||
- 预期输出对应的 KV Cache;
|
||||
- 并发批次的临时显存;
|
||||
- 图像、音频等多模态编码占用;
|
||||
- 保留的安全余量。
|
||||
|
||||
如果预计资源不足,应执行排队、减少输出长度、切换量化模型、切换小模型、转发到其他节点或拒绝请求,而不是冒险提交后等待 OOM。
|
||||
|
||||
### 7.6 连续批处理
|
||||
|
||||
支持连续批处理的推理引擎可以显著提高吞吐量,但调度器仍应限制:
|
||||
|
||||
- 每个批次的最大请求数;
|
||||
- 总输入 Token;
|
||||
- 总预估生成 Token;
|
||||
- 实时任务允许等待成批的最长时间;
|
||||
- 超长请求对其他请求的影响。
|
||||
|
||||
实时场景应优先保障首 Token 延迟,离线任务则可以适当等待以提升批处理效率。
|
||||
|
||||
### 7.7 模型驻留策略
|
||||
|
||||
边缘设备切换模型可能需要数秒到数十秒,因此应将模型分为:
|
||||
|
||||
- **常驻模型**:设备启动后加载,不因普通压力卸载;
|
||||
- **按需模型**:有任务时加载,空闲达到阈值后卸载;
|
||||
- **受限模型**:只有管理员或指定应用能够触发加载;
|
||||
- **禁止模型**:当前硬件条件或安全策略下不能加载。
|
||||
|
||||
调度器应避免模型频繁装入和卸载,可根据最近使用频率、模型加载成本、任务队列和显存压力进行决策。
|
||||
|
||||
---
|
||||
|
||||
## 8. 连接、超时与取消控制
|
||||
|
||||
### 8.1 分层超时
|
||||
|
||||
不得只设置一个笼统的调用超时。建议至少包含:
|
||||
|
||||
| 超时类型 | 含义 | 建议行为 |
|
||||
|---|---|---|
|
||||
| `connect_timeout` | 客户端建立连接的最长时间 | 连接失败,不创建推理任务 |
|
||||
| `queue_timeout` | 请求允许在队列中等待的时间 | 取消排队并返回忙碌或降级结果 |
|
||||
| `first_token_timeout` | 开始执行后等待首 Token 的时间 | 取消任务、切换模型或返回超时 |
|
||||
| `inference_timeout` | 模型实际推理最长时间 | 向推理引擎发送取消信号 |
|
||||
| `idle_timeout` | 流式连接连续无数据的时间 | 检查模型状态并终止异常连接 |
|
||||
| `total_timeout` | 从收到请求到请求结束的总时间 | 强制结束整个调用生命周期 |
|
||||
| `cancel_grace_period` | 发出取消后等待资源释放的时间 | 超过后隔离或重启异常实例 |
|
||||
|
||||
示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"queue_timeout_ms": 5000,
|
||||
"first_token_timeout_ms": 10000,
|
||||
"inference_timeout_ms": 60000,
|
||||
"idle_timeout_ms": 15000,
|
||||
"total_timeout_ms": 90000,
|
||||
"cancel_grace_period_ms": 3000
|
||||
}
|
||||
```
|
||||
|
||||
### 8.2 流式协议选择
|
||||
|
||||
- **SSE**:适合文本生成,浏览器和服务端接入简单;
|
||||
- **WebSocket**:适合实时语音、双向多模态和需要客户端持续上传数据的场景;
|
||||
- **gRPC Streaming**:适合内部服务之间的高性能通信;
|
||||
- **MQTT**:适合设备消息、弱网络和异步边缘任务;
|
||||
- **普通 HTTP**:适合 Embedding、分类和短时非流式任务。
|
||||
|
||||
### 8.3 取消传播
|
||||
|
||||
发生以下情况时必须触发取消:
|
||||
|
||||
- 客户端主动取消;
|
||||
- HTTP、SSE 或 WebSocket 连接断开;
|
||||
- 队列等待超时;
|
||||
- 首 Token 超时;
|
||||
- 推理或总调用超时;
|
||||
- 管理员终止任务;
|
||||
- 应用或用户权限被撤销;
|
||||
- 设备温度、显存或系统负载进入危险状态。
|
||||
|
||||
取消流程必须覆盖网关、队列、调度器、模型适配器和推理引擎。任务最终只能进入 `SUCCEEDED`、`FAILED`、`CANCELLED` 或 `TIMED_OUT` 中的一种终态。
|
||||
|
||||
---
|
||||
|
||||
## 9. 任务状态机
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> RECEIVED
|
||||
RECEIVED --> VALIDATING
|
||||
VALIDATING --> REJECTED: 鉴权、配额或参数失败
|
||||
VALIDATING --> QUEUED: 准入成功
|
||||
QUEUED --> TIMED_OUT: 队列超时
|
||||
QUEUED --> CANCELLED: 用户取消
|
||||
QUEUED --> DISPATCHING: 获得资源
|
||||
DISPATCHING --> RUNNING: 推理实例接受任务
|
||||
DISPATCHING --> FAILED: 模型或节点不可用
|
||||
RUNNING --> STREAMING: 返回首个 Token
|
||||
RUNNING --> TIMED_OUT: 首 Token或推理超时
|
||||
STREAMING --> SUCCEEDED: 正常完成
|
||||
STREAMING --> CANCELLED: 连接断开或主动取消
|
||||
STREAMING --> TIMED_OUT: 空闲或总时间超时
|
||||
STREAMING --> FAILED: 推理异常
|
||||
REJECTED --> [*]
|
||||
TIMED_OUT --> [*]
|
||||
CANCELLED --> [*]
|
||||
FAILED --> [*]
|
||||
SUCCEEDED --> [*]
|
||||
```
|
||||
|
||||
每次状态变化需要记录时间、原因、执行节点、模型实例和操作者,便于故障追踪和服务等级统计。
|
||||
|
||||
---
|
||||
|
||||
## 10. 模型路由与降级
|
||||
|
||||
### 10.1 路由依据
|
||||
|
||||
模型路由器可以根据以下因素做决策:
|
||||
|
||||
- 任务类型和输入模态;
|
||||
- 应用指定的模型能力等级;
|
||||
- 上下文窗口和预估输出长度;
|
||||
- 低延迟或高质量要求;
|
||||
- 数据隐私和出域限制;
|
||||
- 当前模型队列长度;
|
||||
- GPU/NPU 使用率与显存余量;
|
||||
- 模型是否已经加载;
|
||||
- 模型近期错误率;
|
||||
- 设备温度和功耗;
|
||||
- 本地、备用节点和云端调用成本。
|
||||
|
||||
业务应用尽量使用逻辑模型名称,例如 `general-chat`、`fast-chat`、`vision-analysis`,不要直接绑定具体模型版本。通讯层再把逻辑模型映射到实际模型。
|
||||
|
||||
### 10.2 路由示例
|
||||
|
||||
```text
|
||||
简单分类或短问答 → 本地 3B/7B 量化模型
|
||||
普通知识问答 → 本地 7B/14B 模型
|
||||
复杂推理 → 本地大模型或备用边缘节点
|
||||
图片理解 → 本地视觉语言模型
|
||||
语音实时交互 → 流式 ASR + 低延迟 LLM + 流式 TTS
|
||||
高度敏感数据 → 强制本地,禁止云端降级
|
||||
本地设备过载 → 小模型降级、排队或备用节点
|
||||
本地能力不足且允许出域 → 受控路由到云端模型
|
||||
```
|
||||
|
||||
### 10.3 降级顺序
|
||||
|
||||
可按业务策略配置以下降级链:
|
||||
|
||||
1. 同模型的其他本地实例;
|
||||
2. 同一设备上的小型或量化模型;
|
||||
3. 其他边缘算力节点;
|
||||
4. 返回缓存结果或规则化结果;
|
||||
5. 云端模型;
|
||||
6. 明确返回系统繁忙。
|
||||
|
||||
降级不能绕过数据安全策略。每次降级都应在响应元数据和审计日志中记录实际使用的模型及原因。
|
||||
|
||||
---
|
||||
|
||||
## 11. 统一 API 设计
|
||||
|
||||
### 11.1 接口范围
|
||||
|
||||
建议优先兼容 OpenAI API 的核心格式,并增加边缘调度参数:
|
||||
|
||||
```http
|
||||
POST /v1/chat/completions
|
||||
POST /v1/responses
|
||||
POST /v1/embeddings
|
||||
POST /v1/audio/transcriptions
|
||||
POST /v1/audio/speech
|
||||
POST /v1/images/analyze
|
||||
POST /v1/tasks
|
||||
GET /v1/tasks/{task_id}
|
||||
DELETE /v1/tasks/{task_id}
|
||||
POST /v1/sessions
|
||||
GET /v1/sessions/{session_id}
|
||||
DELETE /v1/sessions/{session_id}
|
||||
GET /v1/models
|
||||
GET /health
|
||||
GET /ready
|
||||
```
|
||||
|
||||
### 11.2 请求示例
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "general-chat",
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "请分析设备异常日志并给出处理建议"
|
||||
}
|
||||
],
|
||||
"stream": true,
|
||||
"session_id": "session-001",
|
||||
"idempotency_key": "app01-20260803-00001234",
|
||||
"priority": "P1",
|
||||
"max_output_tokens": 1200,
|
||||
"context_policy": "summary_and_recent",
|
||||
"timeouts": {
|
||||
"queue_ms": 5000,
|
||||
"first_token_ms": 10000,
|
||||
"inference_ms": 60000,
|
||||
"total_ms": 90000
|
||||
},
|
||||
"routing": {
|
||||
"local_only": true,
|
||||
"allow_smaller_model": true
|
||||
},
|
||||
"metadata": {
|
||||
"application": "device-maintenance",
|
||||
"user_id": "user-1001",
|
||||
"trace_id": "trace-abc123"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 11.3 响应元数据
|
||||
|
||||
除模型内容外,建议返回:
|
||||
|
||||
```json
|
||||
{
|
||||
"request_id": "req-20260803-000001",
|
||||
"task_id": "task-20260803-000001",
|
||||
"session_id": "session-001",
|
||||
"status": "succeeded",
|
||||
"logical_model": "general-chat",
|
||||
"actual_model": "qwen3-8b-int4",
|
||||
"node_id": "edge-node-01",
|
||||
"usage": {
|
||||
"input_tokens": 2380,
|
||||
"output_tokens": 615,
|
||||
"total_tokens": 2995
|
||||
},
|
||||
"timing": {
|
||||
"queue_ms": 86,
|
||||
"first_token_ms": 724,
|
||||
"inference_ms": 4380,
|
||||
"total_ms": 4588
|
||||
},
|
||||
"finish_reason": "stop",
|
||||
"degraded": false
|
||||
}
|
||||
```
|
||||
|
||||
### 11.4 错误码
|
||||
|
||||
建议使用稳定的业务错误码,避免应用依赖底层推理引擎的原始错误信息:
|
||||
|
||||
| 错误码 | 含义 |
|
||||
|---|---|
|
||||
| `AUTH_FAILED` | 身份验证失败 |
|
||||
| `PERMISSION_DENIED` | 无模型或数据访问权限 |
|
||||
| `RATE_LIMITED` | 请求频率超过限制 |
|
||||
| `QUOTA_EXCEEDED` | 调用量或 Token 配额不足 |
|
||||
| `INVALID_REQUEST` | 参数或输入格式错误 |
|
||||
| `CONTEXT_TOO_LARGE` | 上下文无法在策略内压缩 |
|
||||
| `QUEUE_FULL` | 队列已满 |
|
||||
| `QUEUE_TIMEOUT` | 排队等待超时 |
|
||||
| `FIRST_TOKEN_TIMEOUT` | 首 Token 超时 |
|
||||
| `INFERENCE_TIMEOUT` | 推理超时 |
|
||||
| `REQUEST_CANCELLED` | 请求已取消 |
|
||||
| `MODEL_UNAVAILABLE` | 模型没有可用实例 |
|
||||
| `RESOURCE_EXHAUSTED` | 显存或执行资源不足 |
|
||||
| `POLICY_BLOCKED` | 安全或数据策略禁止执行 |
|
||||
| `INTERNAL_ERROR` | 通讯层内部错误 |
|
||||
|
||||
---
|
||||
|
||||
## 12. 重试、幂等、熔断与背压
|
||||
|
||||
### 12.1 幂等控制
|
||||
|
||||
客户端可以提交 `idempotency_key`。在有效期内,相同租户、应用和幂等键只能创建一个任务。重复请求应返回原任务状态或结果,避免因网络重试造成重复推理。
|
||||
|
||||
### 12.2 重试策略
|
||||
|
||||
以下情况可以有限重试:
|
||||
|
||||
- 尚未开始推理时节点连接失败;
|
||||
- 模型实例正在重启;
|
||||
- 调度器可以安全切换到等价实例;
|
||||
- Embedding、分类等确定性或近似幂等任务失败。
|
||||
|
||||
以下情况不应自动重试,或必须得到业务策略明确授权:
|
||||
|
||||
- 已经向客户端输出部分 Token;
|
||||
- 工具调用可能产生外部副作用;
|
||||
- 已超过总调用时限;
|
||||
- 请求包含一次性凭证;
|
||||
- 重新生成可能导致业务结果不一致。
|
||||
|
||||
### 12.3 熔断
|
||||
|
||||
当某模型实例在窗口期内出现连续错误、高首 Token 延迟或频繁 OOM,应暂时从路由池移除,进入半开检测状态。熔断范围可分为模型实例、设备节点、云端供应商和具体 API。
|
||||
|
||||
### 12.4 背压
|
||||
|
||||
当系统处理能力低于请求进入速度时,应按顺序采取:
|
||||
|
||||
1. 限制低优先级新请求;
|
||||
2. 缩短低优先级队列允许等待时间;
|
||||
3. 降低单个请求最大输出 Token;
|
||||
4. 将批处理任务延后;
|
||||
5. 路由至备用节点或小模型;
|
||||
6. 返回带 `Retry-After` 的系统繁忙响应。
|
||||
|
||||
不能无限扩张队列,因为过长队列只会把即时失败变成延迟失败。
|
||||
|
||||
---
|
||||
|
||||
## 13. 安全与数据治理
|
||||
|
||||
### 13.1 身份与权限
|
||||
|
||||
- 应用使用 API Key、mTLS 或签名请求接入;
|
||||
- 用户身份可通过 JWT 或可信请求头传递;
|
||||
- 应用只能访问授权的逻辑模型、知识库和工具;
|
||||
- 高风险模型或工具采用单独授权;
|
||||
- 管理接口与业务调用接口分离。
|
||||
|
||||
### 13.2 数据隔离
|
||||
|
||||
会话、日志、缓存、向量数据和 KV Cache 都必须包含租户和用户边界。不得因为缓存命中、批处理或模型复用而向其他租户泄露上下文。
|
||||
|
||||
### 13.3 数据留存
|
||||
|
||||
按数据等级配置:
|
||||
|
||||
- 是否保存原始 Prompt;
|
||||
- 是否保存模型完整输出;
|
||||
- 日志保留天数;
|
||||
- 是否允许进入云端;
|
||||
- 是否允许用于质量评估;
|
||||
- 是否需要脱敏、加密或仅保存哈希;
|
||||
- 用户删除请求的执行范围。
|
||||
|
||||
### 13.4 密钥管理
|
||||
|
||||
云端模型密钥、数据库密码和设备证书不得写入代码、请求日志或普通配置文件。应使用环境密钥、操作系统密钥链或专用 Secret 管理方案。
|
||||
|
||||
---
|
||||
|
||||
## 14. 可观测性与运维
|
||||
|
||||
### 14.1 核心指标
|
||||
|
||||
建议至少采集以下指标:
|
||||
|
||||
**请求指标**
|
||||
|
||||
- 每秒请求数;
|
||||
- 成功率、失败率、取消率和超时率;
|
||||
- P50、P95、P99 总延迟;
|
||||
- 排队时间和队列长度;
|
||||
- 首 Token 延迟;
|
||||
- 输入、输出和总 Token 数;
|
||||
- 每秒输出 Token 数;
|
||||
- 各模型和应用的并发数。
|
||||
|
||||
**资源指标**
|
||||
|
||||
- GPU/NPU/CPU 使用率;
|
||||
- 显存总量、已用量和碎片情况;
|
||||
- KV Cache 使用率和命中率;
|
||||
- 模型加载、卸载次数和耗时;
|
||||
- 设备温度、功耗和降频状态;
|
||||
- 磁盘、内存和网络使用率。
|
||||
|
||||
**质量指标**
|
||||
|
||||
- 模型降级率;
|
||||
- 工具调用成功率;
|
||||
- 上下文裁剪和摘要触发率;
|
||||
- 安全策略拦截次数;
|
||||
- 用户中止率和重新生成率。
|
||||
|
||||
### 14.2 日志与调用链
|
||||
|
||||
每次调用都应使用统一 `request_id`、`task_id`、`session_id` 和 `trace_id` 串联:
|
||||
|
||||
- 网关接入日志;
|
||||
- 上下文组装日志;
|
||||
- 排队和调度日志;
|
||||
- 模型推理日志;
|
||||
- 工具调用日志;
|
||||
- 降级与重试日志;
|
||||
- 取消、超时和资源释放日志。
|
||||
|
||||
日志默认不应完整记录敏感 Prompt。需要排障时,可通过受控采样、脱敏和短期留存开启详细日志。
|
||||
|
||||
### 14.3 告警建议
|
||||
|
||||
- P95 首 Token 延迟持续超过阈值;
|
||||
- 队列使用率超过 80%;
|
||||
- OOM 或模型进程重启;
|
||||
- 某模型错误率持续升高;
|
||||
- GPU 温度或功耗进入危险区间;
|
||||
- 任务取消后资源未及时释放;
|
||||
- 云端降级比例异常增加;
|
||||
- 身份验证失败或策略拦截异常增加。
|
||||
|
||||
---
|
||||
|
||||
## 15. 技术选型建议
|
||||
|
||||
### 15.1 轻量单机版
|
||||
|
||||
适合单台边缘算力机和早期验证:
|
||||
|
||||
- 通讯层:Go、Rust 或 FastAPI;
|
||||
- API:HTTP + SSE,必要时增加 WebSocket;
|
||||
- 队列:进程内优先级队列;
|
||||
- 会话与配置:SQLite;
|
||||
- 可选共享状态:Redis;
|
||||
- 推理引擎:Ollama、llama.cpp 或 vLLM;
|
||||
- 指标:Prometheus;
|
||||
- 展示:Grafana;
|
||||
- 日志:结构化 JSON 日志。
|
||||
|
||||
### 15.2 生产单机或多节点版
|
||||
|
||||
- 通讯层:Go 或 Rust;
|
||||
- 内部通信:gRPC;
|
||||
- 任务状态与短期缓存:Redis;
|
||||
- 配置、会话元数据和审计:PostgreSQL;
|
||||
- 推理:vLLM、TensorRT-LLM、Triton 或厂商 NPU 推理框架;
|
||||
- 调用链:OpenTelemetry;
|
||||
- 指标与告警:Prometheus + Grafana + Alertmanager;
|
||||
- 日志:Loki、OpenSearch 或现有日志平台;
|
||||
- 容器编排:单机 Docker Compose,集群场景使用 Kubernetes 或轻量 K3s。
|
||||
|
||||
### 15.3 选型原则
|
||||
|
||||
- 一台设备优先保证简单、稳定和可恢复,不必过早引入复杂分布式系统;
|
||||
- 推理引擎是否支持连续批处理、请求取消、Token 统计和 KV Cache 管理非常关键;
|
||||
- 通讯层应通过模型适配器隔离具体推理框架,避免框架替换影响 API;
|
||||
- 对实时语音和视频场景,需要单独评估 WebSocket、音视频编解码和端到端延迟。
|
||||
|
||||
---
|
||||
|
||||
## 16. 部署架构建议
|
||||
|
||||
### 16.1 单机部署
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
APP["局域网应用"] --> GW["AI Gateway"]
|
||||
GW --> REDIS["Redis(可选)"]
|
||||
GW --> DB["SQLite / PostgreSQL"]
|
||||
GW --> LLM["LLM 推理服务"]
|
||||
GW --> VLM["视觉推理服务"]
|
||||
GW --> ASR["ASR / TTS 服务"]
|
||||
GW --> MON["Prometheus / Grafana"]
|
||||
LLM --> GPU["GPU / NPU"]
|
||||
VLM --> GPU
|
||||
ASR --> GPU
|
||||
```
|
||||
|
||||
通讯层和推理服务应采用独立进程,避免模型进程崩溃导致 API 和任务状态全部丢失。通讯层需要能够检测并重新接入恢复后的推理实例。
|
||||
|
||||
### 16.2 多节点部署
|
||||
|
||||
多台边缘算力机组成资源池时,需要增加:
|
||||
|
||||
- 节点注册和心跳;
|
||||
- 模型与硬件能力上报;
|
||||
- 全局任务路由;
|
||||
- 节点级熔断;
|
||||
- 数据本地性策略;
|
||||
- 节点断开后的任务恢复;
|
||||
- 跨节点会话与任务状态共享。
|
||||
|
||||
对于需要持续流式输出的任务,一旦开始执行,通常不适合在节点间迁移。节点故障时应明确终止并根据幂等策略决定是否重新执行。
|
||||
|
||||
---
|
||||
|
||||
## 17. 配置示例
|
||||
|
||||
```yaml
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 8080
|
||||
max_request_body_mb: 20
|
||||
|
||||
scheduler:
|
||||
max_running_tasks: 8
|
||||
max_queued_tasks: 500
|
||||
fairness: weighted_fair_queue
|
||||
priority_aging_seconds: 30
|
||||
reserved_realtime_slots: 2
|
||||
|
||||
timeouts:
|
||||
default_queue_ms: 5000
|
||||
default_first_token_ms: 10000
|
||||
default_inference_ms: 60000
|
||||
default_idle_ms: 15000
|
||||
default_total_ms: 90000
|
||||
cancel_grace_period_ms: 3000
|
||||
|
||||
context:
|
||||
safety_margin_ratio: 0.08
|
||||
default_policy: summary_and_recent
|
||||
max_session_messages: 200
|
||||
session_idle_ttl_minutes: 60
|
||||
enable_prompt_persistence: false
|
||||
|
||||
models:
|
||||
general-chat:
|
||||
provider: vllm
|
||||
actual_model: qwen3-8b-int4
|
||||
endpoint: http://127.0.0.1:8001
|
||||
context_window: 32768
|
||||
max_output_tokens: 4096
|
||||
max_concurrency: 4
|
||||
residency: always
|
||||
cancel_supported: true
|
||||
|
||||
fast-chat:
|
||||
provider: ollama
|
||||
actual_model: qwen3:4b
|
||||
endpoint: http://127.0.0.1:11434
|
||||
context_window: 16384
|
||||
max_output_tokens: 2048
|
||||
max_concurrency: 2
|
||||
residency: on_demand
|
||||
idle_unload_seconds: 600
|
||||
|
||||
routing:
|
||||
sensitive_data_local_only: true
|
||||
allow_cloud_fallback_by_default: false
|
||||
overload_strategy:
|
||||
- same_model_other_instance
|
||||
- smaller_local_model
|
||||
- backup_edge_node
|
||||
- reject
|
||||
|
||||
observability:
|
||||
metrics_enabled: true
|
||||
tracing_enabled: true
|
||||
prompt_logging: metadata_only
|
||||
audit_retention_days: 180
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 18. 分阶段实施计划
|
||||
|
||||
### 第一阶段:最小可用版本
|
||||
|
||||
目标是完成单台算力机的统一接入和安全调度:
|
||||
|
||||
1. OpenAI 兼容的文本生成接口;
|
||||
2. API Key 或 JWT 鉴权;
|
||||
3. 单机优先级队列;
|
||||
4. 应用级和模型级并发限制;
|
||||
5. 上下文 Token 预算与基础裁剪;
|
||||
6. 队列、首 Token、推理和总调用超时;
|
||||
7. SSE 流式输出;
|
||||
8. 客户端断开后的推理取消;
|
||||
9. Ollama 或 vLLM 模型适配器;
|
||||
10. 请求、Token、延迟、错误和 GPU 指标。
|
||||
|
||||
### 第二阶段:增强治理能力
|
||||
|
||||
1. 会话持久化与历史摘要;
|
||||
2. Redis 任务状态和幂等控制;
|
||||
3. 动态模型路由和小模型降级;
|
||||
4. 资源准入与显存估算;
|
||||
5. 连续批处理调优;
|
||||
6. 模型驻留和自动卸载;
|
||||
7. 熔断、有限重试和背压;
|
||||
8. 管理后台和实时监控大盘。
|
||||
|
||||
### 第三阶段:多节点与多模态
|
||||
|
||||
1. 多台边缘算力机统一调度;
|
||||
2. 节点注册、心跳和能力上报;
|
||||
3. 视觉、语音和多模态统一接口;
|
||||
4. WebSocket 实时双向通信;
|
||||
5. 本地、备用节点和云端分级路由;
|
||||
6. 多租户计量、配额和成本分析;
|
||||
7. 灰度发布、模型版本管理和效果评估。
|
||||
|
||||
---
|
||||
|
||||
## 19. 验收标准
|
||||
|
||||
### 19.1 功能验收
|
||||
|
||||
- 业务应用能够通过统一接口调用至少两种不同推理引擎;
|
||||
- 模型替换或版本升级时,业务 API 保持兼容;
|
||||
- 可以按应用、用户、模型设置并发和队列上限;
|
||||
- 高优先级请求在资源允许时能够优先执行;
|
||||
- 上下文超限时能够按策略裁剪、摘要或明确拒绝;
|
||||
- 客户端断开后,推理任务能够在规定时间内停止;
|
||||
- 能够查询任务状态并主动取消排队中或执行中的任务;
|
||||
- 所有终态都有明确错误码和可追踪记录;
|
||||
- 敏感数据能够强制仅在本地模型处理。
|
||||
|
||||
### 19.2 性能验收
|
||||
|
||||
具体数值应结合硬件和模型确定,可先采用以下原则性指标:
|
||||
|
||||
- 通讯层自身增加的非排队延迟不超过 20~50 ms;
|
||||
- 空闲设备上的实时请求不因后台任务产生明显排队;
|
||||
- 达到并发上限时系统稳定排队,不发生推理进程级 OOM;
|
||||
- 队列已满时快速返回,不继续消耗连接和内存;
|
||||
- 请求取消后在 `cancel_grace_period` 内释放执行槽位;
|
||||
- 所有请求都能统计排队时间、首 Token 时间和推理时间;
|
||||
- 压力测试期间无任务状态丢失、重复执行或跨租户数据泄露。
|
||||
|
||||
### 19.3 稳定性验收
|
||||
|
||||
- 推理实例重启时,通讯层仍能对外返回明确状态;
|
||||
- 单个模型故障不会拖垮所有模型接口;
|
||||
- Redis、数据库或监控组件短暂异常时有明确降级策略;
|
||||
- 设备达到温度或显存危险阈值时能停止新任务准入;
|
||||
- 通讯层重启后能够恢复或正确终结尚未完成的任务状态。
|
||||
|
||||
---
|
||||
|
||||
## 20. 关键风险与应对措施
|
||||
|
||||
| 风险 | 可能影响 | 应对措施 |
|
||||
|---|---|---|
|
||||
| 显存估算不准确 | OOM、模型崩溃 | 保留安全余量,结合历史数据动态修正 |
|
||||
| 队列过长 | 请求最终超时、内存增长 | 队列上限、等待超时和背压 |
|
||||
| 取消能力不完整 | 连接断开后仍消耗算力 | 选择支持取消的引擎,设置隔离和强制恢复机制 |
|
||||
| 模型频繁换入换出 | 延迟抖动、磁盘和显存压力 | 模型驻留策略和加载成本感知调度 |
|
||||
| 自动重试产生重复结果 | 重复推理或外部副作用 | 幂等键、状态检查和有限重试 |
|
||||
| 上下文跨租户泄露 | 严重安全事故 | 全链路租户标识、缓存隔离和自动化测试 |
|
||||
| 云端降级导致数据出域 | 合规风险 | 默认禁止,按数据级别显式授权和审计 |
|
||||
| 日志记录完整 Prompt | 敏感信息泄露 | 默认只记录元数据,必要时脱敏采样 |
|
||||
| 高优先级任务被滥用 | 普通任务长期饥饿 | 优先级权限控制、公平调度和老化机制 |
|
||||
|
||||
---
|
||||
|
||||
## 21. 最终建议
|
||||
|
||||
边缘 AI 算力机的核心矛盾不是“能否运行模型”,而是有限算力如何被多个应用稳定、安全、公平地共享。统一 AI 通讯层应成为所有 AI 能力的唯一入口,并把一次 AI 调用视为拥有完整生命周期的受控任务。
|
||||
|
||||
业务应用只需要表达:
|
||||
|
||||
- 要完成什么任务;
|
||||
- 使用哪一类模型能力;
|
||||
- 任务优先级;
|
||||
- 最多允许等待多久;
|
||||
- 是否允许降级;
|
||||
- 数据是否允许离开本地;
|
||||
- 期望的输出长度和格式。
|
||||
|
||||
通讯层负责决定:
|
||||
|
||||
- 本次请求能否准入;
|
||||
- 实际携带多少上下文;
|
||||
- 何时进入推理;
|
||||
- 使用哪个模型和节点;
|
||||
- 如何分配 GPU/NPU、显存和执行槽位;
|
||||
- 何时取消、重试、熔断或降级;
|
||||
- 如何返回结果并形成审计记录。
|
||||
|
||||
建设顺序建议从“统一接口、上下文预算、优先级队列、分层超时、请求取消和基础监控”开始。先保证单机环境下的稳定闭环,再逐步扩展模型路由、多模态、多节点和云边协同能力。这样既能快速形成可用产品,也能避免系统在早期被不必要的分布式复杂度拖累。
|
||||
|
||||
Reference in New Issue
Block a user