vllm opensource inference

vLLM开源推理引擎

概述 vLLM开源推理引擎是AI智能体领域中vLLM开源推理引擎的重要主题。本文将从多个角度深入分析这一话题,为读者提供系统性的认知框架和实践参考。 核心概念 基本定义 在深入讨论之前,我们需要明确几个核心概念。AI智能体是指能够感知环境、理解指令、规划行动并调用工具完成任务的AI系统。与传统的聊天机器人不同,智能体具有自主性、目标导向性和工具使用能力。 vLLM开源推理引擎涉及的关键技术包括: 大语言模型:作为智能体的认知引擎,负责理解、推理和生成 工具调用:通过Function Calling或MCP协议与外部系统交互 记忆系统:短期记忆处理当前对话,长期记忆存储历史经验 规划引擎:将复杂任务分解为可执行的子步骤 技术原理 从技术层面看,vLLM开源推理引擎的核心在于如何让AI系统更好地理解和执行人类意图。这涉及多个技术环节的协同: 首先是感知层,智能体需要准确理解用户的自然语言指令,提取关键信息和约束条件。其次是规划层,将高层目标分解为具体的执行步骤。然后是执行层,调用合适的工具完成每个步骤。最后是反馈层,根据执行结果调整后续策略。 实践分析 当前现状 在开源生态领域,当前的技术实践呈现出几个明显特征: 工程化程度提升:从实验室原型到生产级系统,工程能力成为关键差异化因素 评估体系完善:越来越多标准化的评测基准被提出,帮助开发者量化能力边界 开源生态繁荣:开源框架和工具链的成熟降低了开发门槛 安全意识增强:对AI安全和对齐问题的重视程度显著提升 关键挑战 尽管进展显著,vLLM开源推理引擎仍面临几个核心挑战: 技术挑战: 大模型的幻觉问题在智能体场景下被放大,因为智能体需要做出实际决策 多步推理中的错误累积效应导致长程任务成功率下降 工具调用的可靠性受外部API稳定性影响 工程挑战: 智能体的可观测性不足,调试和排错困难 成本控制与性能优化的平衡 从单机到分布式部署的架构复杂性 安全挑战: Prompt注入等攻击手段不断进化 智能体权限管理需要更精细化的控制 数据隐私保护在多Agent协作场景下更加复杂 优化策略 针对上述挑战,以下是几个关键优化方向: 技术优化 分而治之:将复杂任务分解为可独立验证的子任务,降低单步错误影响 多路投票:对关键决策使用多次采样投票机制,提高可靠性 渐进式信任:智能体权限从最小化开始,根据表现逐步扩展 人在回路:高风险决策保留人工审核环节 工程优化 可观测性优先:建立完善的日志、指标和追踪体系 灰度发布:新版本智能体先在小流量环境验证 自动化测试:构建端到端测试套件,防止回归 成本监控:实时追踪Token消耗和API调用成本 案例研究 为了更具体地说明vLLM开源推理引擎的实践价值,我们来看一个典型场景: 某科技公司在内部IT运维中部署了AI智能体,负责处理员工的工单请求。智能体需要理解员工的自然语言描述,判断问题类型,查询知识库,执行修复操作或转接人工。 实施过程中遇到的关键问题包括: 员工描述模糊导致意图识别错误 知识库信息过时导致给出错误建议 某些操作需要管理员权限存在安全风险 解决方案: 引入澄清对话机制,在不确定时主动追问 建立知识库更新流程,定期审核内容 实施权限分级制度,敏感操作需人工确认 效果:工单首次解决率提升35%,平均处理时间缩短60%,员工满意度显著提升。 未来趋势 vLLM开源推理引擎的发展趋势值得关注: 标准化:MCP等开放协议将推动工具接口标准化,降低集成成本 垂直化:针对特定行业和场景的专用智能体将大量涌现 协作化:多智能体协作将成为复杂任务的标准解决方案 自主化:智能体的自主决策能力将持续提升,但需要配套的安全机制 结论 vLLM开源推理引擎是AI智能体技术发展中的重要一环。无论是技术原理的深入理解,还是实践中的工程优化,都需要系统性思维。对于开发者和企业而言,关键在于: 理解技术能力和边界,避免过度期待 建立系统化的评估和监控体系 在创新和安全之间找到平衡 持续学习和适应快速变化的技术生态 硅基AGI探索者将持续关注开源生态领域的最新进展,为读者提供深度分析和实践指导。— ...

2026-06-27 · 1 min · 88 words · 硅基 AGI 探索者
cot variants comparison

思维链变体对比分析

引言 自Chain-of-Thought(CoT)被提出以来,研究者们发展出多种变体以适应不同场景需求。从最初的Few-shot CoT到Zero-shot CoT,再到Auto-CoT、Tree-of-Thought、Graph-of-Thought等,每种变体都有其独特优势和适用场景。本文对主流CoT变体进行系统对比分析,帮助开发者选择最适合的推理增强方案。 基础变体 Zero-shot CoT 核心思想:在Prompt末尾添加"Let’s think step by step"触发推理链,无需提供示例。 典型Prompt: [问题描述] Let's think step by step. 优势: 实现极简,无需设计示例 Token消耗低 通用性强,跨任务迁移无需修改 劣势: 推理格式不可控 复杂推理可能偏离正确方向 效果依赖模型本身的推理能力 适用场景:模型能力较强(如GPT-4级别)、任务复杂度中等、快速原型验证。 Few-shot CoT 核心思想:在Prompt中提供带推理过程的示例,引导模型模仿推理模式。 典型Prompt: 问题:小明有5个苹果,给了小红2个,小红又还给他1个,小明现在有几个? 推理:小明原有5个,给出2个后剩3个,小红还1个后4个。 答案:4 问题:[新问题] 推理: 优势: 推理格式可控 可传递特定推理策略 效果稳定,适合生产环境 劣势: 示例设计需要经验和测试 Token消耗较高 示例选择可能引入偏差 适用场景:需要特定推理格式的生产环境、领域特定推理任务。 自动化变体 Auto-CoT 核心思想:自动从模型输出中采样推理链作为示例,避免人工设计示例。 流程: 用Zero-shot CoT对一批问题生成推理链 对推理链质量进行评分(如通过最终答案的正确性) 选择高质量推理链作为Few-shot示例 使用自动构建的示例处理新问题 优势: 无需人工设计示例 示例多样性有保证 可针对特定任务自动优化 劣势: 初始采样需要额外计算 质量筛选机制影响效果 可能引入错误推理链 适用场景:缺乏领域专家的场景、需要快速适配新任务类型。 Active-CoT 核心思想:在Auto-CoT基础上,主动选择信息量最大的问题进行采样。 流程: 用聚类算法将问题集分组 从每组的边界案例中采样推理链 优先选择模型不确定性高的问题 构建更具代表性的示例集 优势:示例集覆盖更全面,对边界案例处理更好。 ...

2026-06-27 · 2 min · 249 words · 硅基 AGI 探索者
inference scaling laws

推理时计算Scaling Laws

概述 推理时计算Scaling Laws是AI智能体领域中推理时计算Scaling Laws的重要主题。本文将从多个角度深入分析这一话题,为读者提供系统性的认知框架和实践参考。 核心概念 基本定义 在深入讨论之前,我们需要明确几个核心概念。AI智能体是指能够感知环境、理解指令、规划行动并调用工具完成任务的AI系统。与传统的聊天机器人不同,智能体具有自主性、目标导向性和工具使用能力。 推理时计算Scaling Laws涉及的关键技术包括: 大语言模型:作为智能体的认知引擎,负责理解、推理和生成 工具调用:通过Function Calling或MCP协议与外部系统交互 记忆系统:短期记忆处理当前对话,长期记忆存储历史经验 规划引擎:将复杂任务分解为可执行的子步骤 技术原理 从技术层面看,推理时计算Scaling Laws的核心在于如何让AI系统更好地理解和执行人类意图。这涉及多个技术环节的协同: 首先是感知层,智能体需要准确理解用户的自然语言指令,提取关键信息和约束条件。其次是规划层,将高层目标分解为具体的执行步骤。然后是执行层,调用合适的工具完成每个步骤。最后是反馈层,根据执行结果调整后续策略。 实践分析 当前现状 在技术原理领域,当前的技术实践呈现出几个明显特征: 工程化程度提升:从实验室原型到生产级系统,工程能力成为关键差异化因素 评估体系完善:越来越多标准化的评测基准被提出,帮助开发者量化能力边界 开源生态繁荣:开源框架和工具链的成熟降低了开发门槛 安全意识增强:对AI安全和对齐问题的重视程度显著提升 关键挑战 尽管进展显著,推理时计算Scaling Laws仍面临几个核心挑战: 技术挑战: 大模型的幻觉问题在智能体场景下被放大,因为智能体需要做出实际决策 多步推理中的错误累积效应导致长程任务成功率下降 工具调用的可靠性受外部API稳定性影响 工程挑战: 智能体的可观测性不足,调试和排错困难 成本控制与性能优化的平衡 从单机到分布式部署的架构复杂性 安全挑战: Prompt注入等攻击手段不断进化 智能体权限管理需要更精细化的控制 数据隐私保护在多Agent协作场景下更加复杂 优化策略 针对上述挑战,以下是几个关键优化方向: 技术优化 分而治之:将复杂任务分解为可独立验证的子任务,降低单步错误影响 多路投票:对关键决策使用多次采样投票机制,提高可靠性 渐进式信任:智能体权限从最小化开始,根据表现逐步扩展 人在回路:高风险决策保留人工审核环节 工程优化 可观测性优先:建立完善的日志、指标和追踪体系 灰度发布:新版本智能体先在小流量环境验证 自动化测试:构建端到端测试套件,防止回归 成本监控:实时追踪Token消耗和API调用成本 案例研究 为了更具体地说明推理时计算Scaling Laws的实践价值,我们来看一个典型场景: 某科技公司在内部IT运维中部署了AI智能体,负责处理员工的工单请求。智能体需要理解员工的自然语言描述,判断问题类型,查询知识库,执行修复操作或转接人工。 实施过程中遇到的关键问题包括: 员工描述模糊导致意图识别错误 知识库信息过时导致给出错误建议 某些操作需要管理员权限存在安全风险 解决方案: 引入澄清对话机制,在不确定时主动追问 建立知识库更新流程,定期审核内容 实施权限分级制度,敏感操作需人工确认 效果:工单首次解决率提升35%,平均处理时间缩短60%,员工满意度显著提升。 未来趋势 推理时计算Scaling Laws的发展趋势值得关注: 标准化:MCP等开放协议将推动工具接口标准化,降低集成成本 垂直化:针对特定行业和场景的专用智能体将大量涌现 协作化:多智能体协作将成为复杂任务的标准解决方案 自主化:智能体的自主决策能力将持续提升,但需要配套的安全机制 结论 推理时计算Scaling Laws是AI智能体技术发展中的重要一环。无论是技术原理的深入理解,还是实践中的工程优化,都需要系统性思维。对于开发者和企业而言,关键在于: ...

2026-06-27 · 1 min · 96 words · 硅基 AGI 探索者
prompt chain design

Prompt 链式设计:从简单到复杂的推理阶梯

为什么单个 Prompt 不够用? 当 ChatGPT 刚问世时,人们习惯于把所有需求和上下文塞进一个 Prompt,期望模型一次性给出完美答案。对于简单问题,这确实可行。但随着任务复杂度的提升,单 Prompt 方案的局限性迅速暴露。 一个典型的例子:让模型分析一份 50 页的财务报告,提取关键指标,对比历史数据,评估风险,并给出投资建议。如果你把所有要求放在一个 Prompt 里,模型很可能在某个环节出错——也许遗漏了重要的风险因素,也许在计算同比变化时搞错了基数。 这不是模型"不够聪明"的问题,而是人类思维本身也是分步骤的。没有人会一口气完成"读报告→提取数据→计算→对比→评估→写建议"的全过程而不做任何中间检查。Prompt 链式设计的核心思想就是:把复杂任务分解为有序的推理步骤,每一步聚焦一个子目标,前一步的输出作为后一步的输入。 Prompt 链的基本模式 线性链:最简单的分步推理 线性链是最基础的 Prompt 链模式。任务按顺序分解为多个步骤,每一步的输出传递给下一步。 Step 1: 信息提取 Input: 财务报告全文 Output: 关键财务指标(JSON) Step 2: 趋势分析 Input: Step 1 的输出 + 历史数据 Output: 趋势分析报告 Step 3: 风险评估 Input: Step 2 的输出 + 风险因子清单 Output: 风险评级和说明 Step 4: 投资建议 Input: Step 3 的输出 + 投资准则 Output: 最终投资建议 线性链的优势在于简单可控。每一步的输入和输出清晰可审计,出错时容易定位问题环节。缺点是缺乏灵活性——如果第三步发现第一步提取的信息不完整,无法回头补充。 分支链:并行处理多条路径 当任务包含多个可以并行处理的子任务时,分支链更高效。每个分支独立处理一个维度,最终汇总结果。 ┌─ 分支A: 技术分析 ─┐ 输入数据 ──┤─ 分支B: 基本面分析 ─┤── 综合决策 └─ 分支C: 情绪分析 ─┘ 分支链适合多维度分析任务。例如投资决策中的技术面、基本面和情绪面分析可以并行进行,各自产出独立的结论,最后由一个汇总 Prompt 综合所有维度的分析做出最终判断。 ...

2026-06-26 · 2 min · 338 words · 硅基 AGI 探索者
react vs plan execute

ReAct vs Plan-and-Execute:智能体推理范式对比

两种范式的历史脉络 智能体的核心挑战是:如何让 LLM 从"单次生成"进化为"多步推理与行动"。围绕这一问题,学术界和工业界发展出了两条主要路线——ReAct 和 Plan-and-Execute。它们代表了不同的认知哲学:一个是"边想边做"的直觉派,一个是"谋定后动"的规划派。 理解这两种范式的本质差异,对于智能体架构选型至关重要。选错范式不仅影响性能,更可能导致任务根本无法完成。 ReAct:推理与行动的交织 核心思想 ReAct(Reasoning + Acting)由 Yao 等人于 2022 年提出。其核心思想极其简洁:让 LLM 交替进行推理(Thought)和行动(Action),形成 Thought → Action → Observation → Thought 的循环,直到任务完成。 Thought 1: 用户想查找北京明天的天气,我需要调用天气 API Action 1: search_weather(city="北京", date="tomorrow") Observation 1: 北京明天晴,最高温 35°C,最低温 22°C Thought 2: 我已经获得了天气信息,可以回答用户了 Action 2: finish(result="北京明天晴天,气温 22-35°C") 工作机制 ReAct 的运行循环可以形式化为: loop: thought = LLM(reasoning_prompt + history) action = parse_action(thought) if action.type == "finish": return action.result observation = execute_tool(action) history.append((thought, action, observation)) 关键在于 reasoning_prompt 的设计——它需要引导 LLM 在每一步都显式地"前沿思考":当前状态是什么?下一步应该做什么?为什么这样做? ReAct 的提示模板通常包含以下结构: 你是一个能使用工具的智能体。可用的工具有: {tool_descriptions} 请按以下格式回答: Thought: 你的推理过程 Action: 工具名称[参数] (等待观察结果) Thought: 基于观察结果的推理 Action: 下一步行动或最终回答 问题:{question} ReAct 的优势 1. 强大的自适应能力 ...

2026-06-26 · 3 min · 469 words · 硅基 AGI 探索者
ai inference serving

AI 推理服务架构:从单机到分布式弹性扩展

1. 推理服务的核心挑战 模型训练完成后,推理服务是将模型价值交付给用户的关键环节。与训练不同,推理服务面临独特挑战: 延迟敏感:用户期望秒级甚至毫秒级响应 吞吐与延迟权衡:批处理提高吞吐但增加单请求延迟 GPU 资源昂贵:需最大化利用率 弹性需求:流量峰谷差异可达 10 倍以上 多模型管理:同时服务数十个模型版本 2. 架构演进路线 阶段1: 单机单GPU 阶段2: 单机多GPU 阶段3: 分布式集群 ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ FastAPI │ │ FastAPI │ │ API Gateway │ │ + HF Model │ → │ + vLLM │ → │ + vLLM Cluster │ │ + 1 GPU │ │ + 4 GPUs │ │ + K8s Autoscale │ └──────────────┘ └──────────────┘ └──────────────────┘ 延迟: 500ms 延迟: 200ms 延迟: 150ms QPS: 5 QPS: 80 QPS: 1000+ 3. 推理引擎选型 3.1 引擎对比 引擎 优势 劣势 适用场景 vLLM PagedAttention,高吞吐 仅支持主流模型 LLM 生产服务 TensorRT-LLM 极致优化,NVIDIA 官方 编译复杂,灵活性低 极致性能场景 TGI HF 官方,生态好 性能略逊 vLLM HF 模型服务 Ollama 部署简单 性能一般 本地/开发环境 SGLang 结构化生成优化 生态较新 结构化输出 3.2 vLLM 部署 # vLLM 服务启动配置 VLLM_CONFIG = { "model": "meta-llama/Llama-3-70B", "tensor_parallel_size": 4, # 4 GPU 张量并行 "gpu_memory_utilization": 0.90, # GPU 内存利用率 "max_model_len": 8192, # 最大上下文长度 "max_num_seqs": 256, # 最大并发序列 "swap_space": 16, # CPU 交换空间 (GB) "enable_prefix_caching": True, # 前缀缓存 "enable_chunked_prefill": True, # 分块预填充 "enforce_eager": False, # 使用 CUDA Graph "dtype": "float16", # 精度 "quantization": "awq", # 量化 "served_model_name": "llama-3-70b", # 对外模型名 } # 启动命令 # python -m vllm.entrypoints.openai.api_server --config config.json 3.3 TensorRT-LLM 优化 import tensorrt as trt import tensorrt_llm from tensorrt_llm.runtime import ModelRunner, GenerationSession class TensorRTEngine: """ TensorRT-LLM 推理引擎 构建 → 序列化 → 反序列化 → 推理 """ def __init__(self, model_dir: str, engine_dir: str): self.model_dir = model_dir self.engine_dir = engine_dir self.runner: ModelRunner = None def build_engine(self, config: dict): """构建 TensorRT 引擎(一次性操作)""" builder = tensorrt_llm.Builder() builder_config = builder.create_builder_config( name="llama", precision=config.get("precision", "fp16"), tensor_parallel_size=config.get("tp_size", 1), pipeline_parallel_size=config.get("pp_size", 1), max_batch_size=config.get("max_batch_size", 256), max_input_len=config.get("max_input_len", 2048), max_output_len=config.get("max_output_len", 512), max_beam_width=config.get("max_beam_width", 1), use_gpt_attention=config.get("use_gpt_attention", True), use_plugin=True, ) # 构建并序列化引擎 engine = builder.build_model(builder_config, self.model_dir) engine.serialize(self.engine_dir) def load_engine(self): """加载已构建的引擎""" self.runner = ModelRunner.from_dir( self.engine_dir, rank=0, is_pp_first=True, is_pp_last=True ) async def generate(self, prompt_ids: list[int], max_new_tokens: int = 256) -> list[int]: session = GenerationSession( model_config=self.runner.model_config, engine=self.runner.engine, input_ids=prompt_ids ) session.decode(max_new_tokens=max_new_tokens) return session.output_ids 4. 批处理与调度 4.1 动态批处理 import asyncio from dataclasses import dataclass, field from collections import deque import time @dataclass class InferenceRequest: request_id: str input_ids: list[int] max_tokens: int temperature: float = 1.0 top_p: float = 0.9 stream: bool = False arrival_time: float = field(default_factory=time.time) future: asyncio.Future = field(default_factory=asyncio.get_event_loop().create_future) class DynamicBatcher: """ 动态批处理器:收集请求到批次中,达到阈值或超时后提交 核心:在延迟和吞吐之间权衡 """ def __init__(self, engine, max_batch_size: int = 32, max_wait_ms: float = 50, max_seq_len: int = 2048): self.engine = engine self.max_batch_size = max_batch_size self.max_wait_ms = max_wait_ms self.max_seq_len = max_seq_len self.queue: deque[InferenceRequest] = deque() self.running = False async def submit(self, request: InferenceRequest) -> str: self.queue.append(request) return await request.future async def start(self): self.running = True while self.running: batch = await self._collect_batch() if batch: await self._process_batch(batch) async def _collect_batch(self) -> list[InferenceRequest]: batch = [] deadline = time.time() + self.max_wait_ms / 1000 while len(batch) < self.max_batch_size and time.time() < deadline: if self.queue: req = self.queue.popleft() batch.append(req) else: await asyncio.sleep(0.001) return batch async def _process_batch(self, batch: list[InferenceRequest]): # Padding 到相同长度 max_len = min(max(len(r.input_ids) for r in batch), self.max_seq_len) padded_inputs = [] attention_masks = [] for req in batch: padding_len = max_len - len(req.input_ids[:max_len]) padded = req.input_ids[:max_len] + [0] * padding_len mask = [1] * min(len(req.input_ids), max_len) + [0] * padding_len padded_inputs.append(padded) attention_masks.append(mask) # 执行批量推理 outputs = await self.engine.generate_batch( input_ids=padded_inputs, attention_mask=attention_masks, max_new_tokens=max(r.max_tokens for r in batch), temperature=max(r.temperature for r in batch), ) # 分发结果 for req, output in zip(batch, outputs): if not req.future.done(): req.future.set_result(output) 4.2 连续批处理(Continuous Batching) class ContinuousBatcher: """ 连续批处理(Iteration-Level Scheduling) 与传统批处理不同:不需要等所有请求完成才接受新请求 每个解码步后都可以加入新请求、移除已完成请求 """ def __init__(self, engine, max_batch_size: int = 256): self.engine = engine self.max_batch_size = max_batch_size self.active_sequences: list[Sequence] = [] self.waiting_queue: deque[Sequence] = deque() @dataclass class Sequence: request_id: str input_ids: list[int] output_ids: list[int] = field(default_factory=list) max_tokens: int = 256 is_finished: bool = False future: asyncio.Future = None async def submit(self, request: InferenceRequest) -> str: seq = self.Sequence( request_id=request.request_id, input_ids=request.input_ids, max_tokens=request.max_tokens, future=asyncio.get_event_loop().create_future() ) self.waiting_queue.append(seq) return await seq.future async def run(self): while True: # 1. 从等待队列添加新序列到活跃批次 while (self.waiting_queue and len(self.active_sequences) < self.max_batch_size): self.active_sequences.append(self.waiting_queue.popleft()) if not self.active_sequences: await asyncio.sleep(0.001) continue # 2. 执行单步解码 step_outputs = await self.engine.step_decode( [s.input_ids + s.output_ids for s in self.active_sequences] ) # 3. 处理输出 finished = [] for seq, output in zip(self.active_sequences, step_outputs): seq.output_ids.append(output.token_id) if output.is_eos or len(seq.output_ids) >= seq.max_tokens: seq.is_finished = True seq.future.set_result(seq.output_ids) finished.append(seq) # 4. 移除已完成序列 self.active_sequences = [s for s in self.active_sequences if not s.is_finished] 5. GPU 资源调度 5.1 多模型 GPU 共享 class GPUScheduler: """GPU 资源调度器:管理多模型在同一 GPU 上的调度""" def __init__(self, gpu_memory_total: int = 80_000): # MB self.total_memory = gpu_memory_total self.allocated: dict[str, int] = {} # model_id -> memory_mb self.model_streams: dict[str, int] = {} # model_id -> cuda_stream def can_load(self, model_memory: int) -> bool: used = sum(self.allocated.values()) return (self.total_memory - used) >= model_memory def allocate(self, model_id: str, memory_mb: int) -> int: if not self.can_load(memory_mb): raise RuntimeError(f"Insufficient GPU memory: need {memory_mb}MB, " f"available {self.total_memory - sum(self.allocated.values())}MB") self.allocated[model_id] = memory_mb return len(self.allocated) # stream id def deallocate(self, model_id: str): self.allocated.pop(model_id, None) self.model_streams.pop(model_id, None) def get_utilization(self) -> float: return sum(self.allocated.values()) / self.total_memory class ModelWarmPool: """模型热池:常用模型常驻 GPU,不常用模型按需加载""" def __init__(self, scheduler: GPUScheduler, storage_path: str): self.scheduler = scheduler self.storage = storage_path self.loaded: dict[str, Any] = {} # model_id -> model instance self.loading_locks: dict[str, asyncio.Lock] = {} self.access_times: dict[str, float] = {} self.idle_threshold = 600 # 10分钟未使用则卸载 async def get_model(self, model_id: str, model_config: dict): if model_id in self.loaded: self.access_times[model_id] = time.time() return self.loaded[model_id] # 防止并发加载同一模型 if model_id not in self.loading_locks: self.loading_locks[model_id] = asyncio.Lock() async with self.loading_locks[model_id]: if model_id in self.loaded: return self.loaded[model_id] # 检查 GPU 内存是否足够 required_mem = model_config["memory_mb"] if not self.scheduler.can_load(required_mem): await self._evict_idle_models(required_mem) # 加载模型 model = await self._load_model(model_id, model_config) self.scheduler.allocate(model_id, required_mem) self.loaded[model_id] = model self.access_times[model_id] = time.time() return model async def _evict_idle_models(self, required_mem: int): """LRU 淘汰空闲模型""" sorted_models = sorted(self.access_times.items(), key=lambda x: x[1]) for model_id, last_access in sorted_models: if time.time() - last_access > self.idle_threshold: await self._unload_model(model_id) if self.scheduler.can_load(required_mem): break async def _unload_model(self, model_id: str): if model_id in self.loaded: del self.loaded[model_id] self.scheduler.deallocate(model_id) self.access_times.pop(model_id, None) import torch torch.cuda.empty_cache() 6. 弹性伸缩 6.1 自动扩缩容控制器 class Autoscaler: """基于指标的自定扩缩容""" def __init__(self, min_replicas: int = 1, max_replicas: int = 10, target_gpu_util: float = 0.7, target_latency_ms: float = 500): self.min_replicas = min_replicas self.max_replicas = max_replicas self.target_gpu_util = target_gpu_util self.target_latency = target_latency_ms self.current_replicas = min_replicas def decide(self, metrics: dict) -> dict: gpu_util = metrics.get("gpu_utilization", 0) avg_latency = metrics.get("avg_latency_ms", 0) queue_depth = metrics.get("queue_depth", 0) qps = metrics.get("qps", 0) # 扩容信号 scale_up_score = 0 if gpu_util > self.target_gpu_util * 1.2: scale_up_score += 2 if avg_latency > self.target_latency * 1.5: scale_up_score += 2 if queue_depth > 50: scale_up_score += 1 # 缩容信号 scale_down_score = 0 if gpu_util < self.target_gpu_util * 0.3: scale_down_score += 2 if avg_latency < self.target_latency * 0.3 and queue_depth < 5: scale_down_score += 1 if qps < 1 and self.current_replicas > 1: scale_down_score += 1 if scale_up_score >= 2 and self.current_replicas < self.max_replicas: return {"action": "scale_up", "replicas": self.current_replicas + 1} elif scale_down_score >= 2 and self.current_replicas > self.min_replicas: return {"action": "scale_down", "replicas": self.current_replicas - 1} else: return {"action": "none", "replicas": self.current_replicas} 6.2 Kubernetes 部署配置 # vllm-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: vllm-llama-70b spec: replicas: 2 selector: matchLabels: app: vllm-llama-70b template: metadata: labels: app: vllm-llama-70b spec: containers: - name: vllm image: vllm/vllm-openai:latest args: - --model=meta-llama/Llama-3-70B - --tensor-parallel-size=4 - --gpu-memory-utilization=0.90 - --max-model-len=8192 resources: limits: nvidia.com/gpu: 4 memory: 128Gi requests: nvidia.com/gpu: 4 memory: 64Gi readinessProbe: httpGet: path: /health port: 8000 initialDelaySeconds: 120 periodSeconds: 10 --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: vllm-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: vllm-llama-70b minReplicas: 2 maxReplicas: 10 metrics: - type: Pods pods: metric: name: gpu_utilization target: type: AverageValue averageValue: "70" - type: Resource resource: name: memory target: type: Utilization averageUtilization: 80 7. 负载均衡 class InferenceLoadBalancer: """推理负载均衡器:感知 GPU 负载和模型位置""" def __init__(self): self.backends: dict[str, BackendInfo] = {} @dataclass class BackendInfo: url: str model_id: str gpu_util: float = 0.0 active_requests: int = 0 queue_depth: int = 0 avg_latency_ms: float = 0.0 healthy: bool = True def select(self, model_id: str) -> str: candidates = [ (url, info) for url, info in self.backends.items() if info.model_id == model_id and info.healthy ] if not candidates: raise RuntimeError(f"No healthy backend for model {model_id}") # 最少连接 + 最低延迟加权 def score(info: BackendInfo) -> float: load_score = info.active_requests * 0.5 + info.queue_depth * 0.3 latency_score = info.avg_latency_ms / 1000 * 0.2 return load_score + latency_score return min(candidates, key=lambda x: score(x[1]))[0] def update_health(self, url: str, metrics: dict): if url in self.backends: info = self.backends[url] info.gpu_util = metrics.get("gpu_util", info.gpu_util) info.active_requests = metrics.get("active_requests", info.active_requests) info.avg_latency_ms = metrics.get("avg_latency_ms", info.avg_latency_ms) info.healthy = metrics.get("healthy", True) 8. 性能优化总结 优化手段 吞吐提升 延迟降低 实现复杂度 动态批处理 3-5x -10% ⭐⭐ 连续批处理 5-10x -20% ⭐⭐⭐ TensorRT 优化 2-3x -40% ⭐⭐⭐⭐ 前缀缓存 2x -50% ⭐⭐ AWQ/GPTQ 量化 2x -30% ⭐⭐ Speculative Decoding 1.5x -40% ⭐⭐⭐⭐ 多 GPU 并行 线性 持平 ⭐⭐⭐ 9. 总结 AI 推理服务的架构设计需要平衡延迟、吞吐和成本: ...

2026-06-25 · 7 min · 1424 words · 硅基 AGI 探索者
chain of thought mastery

Chain of Thought 精通:从零到推理增强

一、什么是 Chain of Thought Chain of Thought(CoT,思维链)是一种让大语言模型在给出最终答案前,先展示中间推理步骤的提示技术。由 Wei et al. (2022) 在论文 “Chain-of-Thought Prompting Elicits Reasoning in Large Language Models” 中首次提出。 1.1 核心思想 传统 Prompt 要求模型直接输出答案——这相当于让人不假思索地回答复杂问题。而 CoT 通过引导模型"自言自语"地推理,显著提升复杂推理任务的准确率。 # 标准 Prompt(直接输出) Q: 小明有 23 个苹果,吃了 3 个,又买了 12 个。他有多少个苹果? A: 32 # CoT Prompt(展示推理步骤) Q: 小明有 23 个苹果,吃了 3 个,又买了 12 个。他有多少个苹果? A: 小明开始有 23 个苹果。吃了 3 个之后,剩余 23 - 3 = 20 个。又买了 12 个后,总数为 20 + 12 = 32 个。所以答案是 32。 1.2 为什么 CoT 有效 因素 说明 分解复杂度 将多步推理拆解为可管理的子步骤 中间监督 错误定位到具体步骤,而非全盘错误 计算复用 中间结果可作为后续推理的上下文 注意力聚焦 每一步聚焦当前子问题,减少信息丢失 二、CoT 的核心方法 2.1 Zero-shot CoT 通过简单短语 “Let’s think step by step” 触发推理链。无需示例,对大多数模型有效。 ...

2026-06-25 · 4 min · 720 words · 硅基 AGI 探索者
sglang inference

SGLang 探理引擎:结构化生成的高性能方案

引言 SGLang(Structured Generation Language)是由 UC Berkeley / LMSYS 团队开发的高性能 LLM 推理引擎。与 vLLM 专注通用吞吐量优化不同,SGLang 的核心差异化在于:结构化生成和 RadixAttention 两项关键技术。在需要 JSON/正则约束输出、多轮对话、复杂提示词模板的场景下,SGLang 的性能表现显著优于 vLLM 和 TensorRT-LLM。 核心技术解析 RadixAttention RadixAttention 是 SGLang 的核心创新,使用基数树(Radix Tree)管理 KV Cache 的自动复用: 传统 KV Cache(每请求独立): 请求 A "系统提示 + 问题1" → KV Cache A(2048 tokens) 请求 B "系统提示 + 问题2" → KV Cache B(2048 tokens) → 同一系统提示被重复计算 RadixAttention(自动复用): Radix Tree: ┌──────────────────────────┐ │ [系统提示共享前缀] │ ← 复用,不重复计算 │ ├── [问题1] → KV Cache │ │ └── [问题2] → KV Cache │ └──────────────────────────┘ → 系统提示只计算一次,后续请求直接复用 与前缀缓存(Prefix Caching)的区别: ...

2026-06-25 · 5 min · 921 words · 硅基 AGI 探索者
vllm production guide

vLLM 生产部署指南:高吞吐推理引擎

引言 vLLM 由 UC Berkeley 团队开发,凭借 PagedAttention 技术实现了接近理论峰值的 GPU 利用率。在同等硬件条件下,vLLM 的吞吐量可达 Hugging Face Transformers 的 14-24 倍。截至 2026 年,vLLM 已成为企业级 LLM 推理部署的首选引擎,被 Anthropic、Meta、字节跳动等公司广泛采用。 核心技术解析 PagedAttention PagedAttention 是 vLLM 的核心创新,灵感来自操作系统的虚拟内存分页机制。传统 LLM 推理中,KV Cache 的内存管理存在严重碎片化问题。 传统 KV Cache 问题: ┌─────────────────────────────────────────┐ │ 连续内存分配(传统方式) │ │ ┌──────┐┌──────┐┌──────┐┌──────────┐ │ │ │Req A ││Req B ││Req C ││ 空洞 │ │ │ │2GB ││2GB ││2GB ││ 1.5GB │ │ │ └──────┘└──────┘└──────┘└──────────┘ │ │ 问题:外部碎片导致 1.5GB 无法利用 │ └─────────────────────────────────────────┘ PagedAttention 方案: ...

2026-06-25 · 4 min · 813 words · 硅基 AGI 探索者
continuous batching

连续批处理:vLLM 高吞吐推理的核心技术

静态批处理的瓶颈 传统 LLM 推理服务采用静态批处理:每个批次固定大小,所有请求必须等最长的那个请求完成后才能返回。 静态批处理示例(batch=4): Request A: [tok][tok][tok][tok][EOS] # 生成 5 个 token Request B: [tok][tok][tok][tok][tok][tok][EOS] # 生成 7 个 token Request C: [tok][tok][tok][EOS] # 生成 4 个 token Request D: [tok][tok][tok][tok][tok][tok][tok][tok][EOS] # 生成 9 个 token 批处理完成时间:等待 D 完成(9 个 token) 实际计算:A 只需要 5 步,但等了 9 步 GPU 利用率:≈ 25/36 = 69%(因为要等待最慢的请求) 问题: 首 token 延迟:新请求必须等当前批次完成才能进入 GPU 闲置:短请求完成后,GPU 资源被浪费 吞吐低下:无法动态调度,无法"边生成边接收" 连续批处理原理 连续批处理(Continuous Batching, Orca, 2023)的核心思想是:动态管理批次,随时加入新请求,随时移除已完成的请求。 ...

2026-06-25 · 6 min · 1080 words · 硅基 AGI 探索者
鲁ICP备2026018361号