小米 MiMo-v2.5-Pro-UltraSpeed 以 1000 tokens/s 的生成速度震惊了整个 AI 社区——一个万亿参数级别的模型,推理速度却比一年前的 7B 模型还快。这背后不是单一黑科技,而是一整条推理优化链路的工程协同。如果你正在生产环境部署大模型,却只做了量化或只用了 vLLM 默认配置,那你可能只拿到了 30% 的性能。
本文不是重复讲解某个单一优化技术——那些我们在 推理流程深度解析、KV Cache 优化、投机解码指南 中已经详细覆盖。本文要解决的问题是:如何把这些技术组合成一条完整的优化链路,在真实生产环境中实现 10 倍甚至 100 倍的性能提升。
🔍 一、优化前必做:定位你的瓶颈在哪里
1.1 Memory-Bound vs Compute-Bound:90% 的人搞反了
LLM 推理的性能瓶颈只有两种:内存带宽受限(Memory-Bound) 和 计算能力受限(Compute-Bound)。绝大多数生产场景下,瓶颈是前者。
以 Llama-3.1-70B 为例,模型权重约 140GB(FP16),即使使用 A100 80GB GPU,也需要至少 2 张卡。每次生成一个 token,GPU 需要从显存读取全部 140GB 权重——这就是为什么 batch size = 1 时,GPU 算力利用率通常不到 5%。
📌 记住: 如果你的 batch size 只有 1,无论用多好的 GPU,推理速度都不会快——因为瓶颈在显存带宽,不在算力。优化的第一步是增大 batch size,让 GPU 算力被充分利用。
1.2 用 Profiling 找到真实瓶颈
不要凭感觉优化。用以下工具量化你的瓶颈:
# profiling_inference.py — 用 PyTorch Profiler 定位推理瓶颈
import torch
from torch.profiler import profile, record_function, ProfilerActivity
def profile_inference(model, input_ids, max_new_tokens=50):
"""Profile LLM inference to identify bottlenecks"""
with profile(
activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA],
record_shapes=True,
profile_memory=True,
with_stack=True
) as prof:
with record_function("prefill"):
# Prefill phase — compute-bound for long prompts
output = model.generate(
input_ids,
max_new_tokens=1,
do_sample=False
)
with record_function("decode"):
# Decode phase — memory-bound
output = model.generate(
input_ids,
max_new_tokens=max_new_tokens,
do_sample=False
)
# Print CUDA time breakdown
print(prof.key_averages().table(
sort_by="cuda_time_total", row_limit=15
))
# Print memory usage
print(f"\nPeak memory: {torch.cuda.max_memory_allocated() / 1e9:.2f} GB")
return prof
关键指标解读:
| 指标 | 含义 | 优化方向 |
|---|---|---|
| GPU 利用率 < 30% | Memory-Bound,batch 太小 | 增大 batch size,启用 Continuous Batching |
| GPU 利用率 > 80% | Compute-Bound | 量化减少计算量,或换更强 GPU |
| KV Cache 占用 > 60% 显存 | KV Cache 是瓶颈 | 启用 PagedAttention,压缩 KV Cache |
| Prefill 时间 > 50% 总时间 | 长 prompt 场景 | 启用 Prefix Caching,Chunked Prefill |
1.3 建立性能基线
优化前必须记录基线数据,否则你无法衡量改进效果:
# 用 vLLM benchmark 工具建立基线
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-8B-Instruct \
--tensor-parallel-size 1 \
--max-model-len 4096
# 另一个终端运行 benchmark
python benchmark_serving.py \
--backend openai \
--base-url http://localhost:8000 \
--model meta-llama/Llama-3.1-8B-Instruct \
--dataset-name sharegpt \
--dataset-path ShareGPT_V3_unfiltered_cleaned_split.json \
--num-prompts 200 \
--request-rate 10
⚠️ 警告: 永远不要在没有基线数据的情况下开始优化。没有基线,你做的所有改动都是盲人摸象。
⚡ 二、核心优化三板斧:Batching + Caching + Quantization
2.1 Continuous Batching:吞吐量提升 5-20 倍的关键
传统 static batching 的问题:一批请求必须等最长的那个完成,GPU 在等待期间完全空闲。
Continuous Batching(连续批处理) 的核心思想:当一个请求完成生成时,立即插入新请求,GPU 永远不空闲。
# continuous_batching_demo.py — 模拟 Continuous Batching 的核心逻辑
import asyncio
from dataclasses import dataclass, field
from typing import Optional
@dataclass
class InferenceRequest:
request_id: str
prompt_tokens: list[int]
max_tokens: int
generated_tokens: list[int] = field(default_factory=list)
is_complete: bool = False
class ContinuousBatchScheduler:
"""Simplified continuous batching scheduler"""
def __init__(self, max_batch_size: int = 32):
self.max_batch_size = max_batch_size
self.running: list[InferenceRequest] = []
self.waiting: list[InferenceRequest] = []
def add_request(self, request: InferenceRequest):
self.waiting.append(request)
def schedule_batch(self) -> list[InferenceRequest]:
"""Fill batch: remove completed, add waiting requests"""
# Remove completed requests
self.running = [r for r in self.running if not r.is_complete]
# Fill empty slots with waiting requests
slots_available = self.max_batch_size - len(self.running)
while slots_available > 0 and self.waiting:
self.running.append(self.waiting.pop(0))
slots_available -= 1
return self.running
def step(self) -> dict[str, list[int]]:
"""Execute one decode step for all running requests"""
batch = self.schedule_batch()
results = {}
for req in batch:
# Simulate generating one token
new_token = len(req.generated_tokens) # placeholder
req.generated_tokens.append(new_token)
if len(req.generated_tokens) >= req.max_tokens:
req.is_complete = True
results[req.request_id] = req.generated_tokens
return results
# Demo
scheduler = ContinuousBatchScheduler(max_batch_size=8)
for i in range(20):
scheduler.add_request(InferenceRequest(
request_id=f"req-{i}",
prompt_tokens=list(range(100)),
max_tokens=50 + i * 5 # Different lengths!
))
# Each step processes all active requests simultaneously
for step in range(150):
results = scheduler.step()
active = len(scheduler.running)
waiting = len(scheduler.waiting)
if step % 10 == 0:
print(f"Step {step}: active={active}, waiting={waiting}")
if not scheduler.running and not scheduler.waiting:
print(f"All requests completed at step {step}")
break
配置 Continuous Batching(vLLM):
# vLLM 默认启用 Continuous Batching,关键参数:
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 2 \
--max-num-seqs 64 \ # 最大并发请求数(影响显存)
--max-num-batched-tokens 8192 \ # 单步最大 token 数
--enable-chunked-prefill \ # 长 prompt 分块处理
--gpu-memory-utilization 0.9 # GPU 显存利用率目标
💡 提示:
max-num-seqs不是越大越好。设太大会导致每个请求分到的 KV Cache 变少,可能触发 preemption。建议从 32 开始,逐步调大观察延迟变化。
2.2 Prefix Caching:多轮对话和 RAG 场景的杀手锏
在多轮对话和 RAG 场景中,每次请求的 prompt 前缀(system prompt + 知识库检索结果)往往是相同的。Prefix Caching 将这些共同前缀的 KV Cache 缓存起来,避免重复计算。
# Prefix Caching 的效果对比
❌ 无 Prefix Caching:
请求 1: [System Prompt (200 tokens)] + [用户问题 1] → 计算 250 tokens
请求 2: [System Prompt (200 tokens)] + [用户问题 2] → 计算 250 tokens
请求 3: [System Prompt (200 tokens)] + [用户问题 3] → 计算 250 tokens
总计算量: 750 tokens
✅ 有 Prefix Caching:
请求 1: [System Prompt (200 tokens)] + [用户问题 1] → 计算 250 tokens (缓存)
请求 2: [System Prompt (200 tokens)] + [用户问题 2] → 计算 50 tokens (命中缓存!)
请求 3: [System Prompt (200 tokens)] + [用户问题 3] → 计算 50 tokens (命中缓存!)
总计算量: 350 tokens — 节省 53%
# SGLang 启用 RadixAttention(自动 Prefix Caching)
python -m sglang.launch_server \
--model-path meta-llama/Llama-3.1-8B-Instruct \
--enable-radix-attention \ # 核心:基于 Radix Tree 的前缀缓存
--mem-fraction-static 0.8 \ # 静态显存分配比例
--chunked-prefill-size 4096 # 分块预填充大小
# vLLM 启用 Automatic Prefix Caching
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-8B-Instruct \
--enable-prefix-caching \ # 启用前缀缓存
--max-model-len 4096
Prefix Caching 在不同场景下的效果对比:
| 场景 | 前缀占比 | 命中率 | Prefill 加速 |
|---|---|---|---|
| 单轮聊天 | 0% | 0% | 无 |
| 多轮对话 | 30-50% | 60-80% | 1.5-2x |
| RAG 应用 | 60-80% | 85-95% | 3-5x |
| Agent 系统 | 40-60% | 70-90% | 2-3x |
| 代码补全 | 50-70% | 75-90% | 2-4x |
⚠️ 警告: Prefix Caching 需要额外显存存储缓存。如果显存紧张,需要降低
gpu-memory-utilization或减少max-num-seqs来腾出空间。
2.3 量化选型:不是越低越好
量化是用更少的比特位表示模型权重,减少显存占用和内存带宽需求。但量化是有代价的——模型质量会下降。
| 量化方式 | 权重位数 | 显存节省 | 质量损失 | 推荐场景 |
|---|---|---|---|---|
| FP16/BF16 | 16-bit | 基准 | 无 | 训练、精度敏感任务 |
| FP8 | 8-bit | 50% | 极小 | 生产首选,H100 原生支持 |
| GPTQ INT4 | 4-bit | 75% | 小 | 显存受限,质量要求高 |
| AWQ INT4 | 4-bit | 75% | 小 | 与 vLLM 集成最好 |
| GGUF Q4_K_M | 4-bit | 75% | 中 | llama.cpp 本地部署 |
| GPTQ INT3 | 3-bit | 81% | 中 | 极端显存受限 |
| Q2_K | 2-bit | 87% | 大 | 实验性,不推荐生产 |
# quantization_compare.py — 对比不同量化方式的模型质量
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
import time
def benchmark_model(model_path: str, prompt: str, max_tokens: int = 100):
"""Benchmark a model's inference speed and output quality"""
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(
model_path,
torch_dtype=torch.float16,
device_map="auto"
)
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
# Warmup
with torch.no_grad():
model.generate(**inputs, max_new_tokens=1)
# Benchmark
torch.cuda.synchronize()
start = time.perf_counter()
with torch.no_grad():
output = model.generate(
**inputs,
max_new_tokens=max_tokens,
do_sample=False
)
torch.cuda.synchronize()
elapsed = time.perf_counter() - start
generated = output[0][inputs["input_ids"].shape[1]:]
tokens_generated = len(generated)
tokens_per_sec = tokens_generated / elapsed
print(f"Model: {model_path}")
print(f"Tokens: {tokens_generated}, Time: {elapsed:.2f}s")
print(f"Speed: {tokens_per_sec:.1f} tokens/s")
print(f"Output: {tokenizer.decode(generated[:50])}...")
print(f"Memory: {torch.cuda.max_memory_allocated() / 1e9:.2f} GB")
print("-" * 60)
return tokens_per_sec
# 对比:需要先用 AutoGPTQ/AWQ 量化模型
# benchmark_model("meta-llama/Llama-3.1-8B-Instruct", "Explain quantum computing")
# benchmark_model("TheBloke/Llama-3.1-8B-Instruct-GPTQ", "Explain quantum computing")
💡 提示: 如果你用 H100/A100,优先用 FP8——它几乎无质量损失,且 GPU 硬件原生支持。只有在消费级 GPU(RTX 4090 等)上部署时,才需要考虑 INT4 量化。
🏗️ 三、生产级部署架构:组合技的威力
3.1 单卡极致优化:RTX 4090 上跑 70B 模型
单卡部署的核心挑战是显存不够。以 RTX 4090(24GB 显存)为例:
| 模型 | FP16 显存 | INT4 显存 | 4090 可行性 |
|---|---|---|---|
| Llama-3.1-8B | 16GB | 5GB | ✅ FP16 可跑 |
| Llama-3.1-70B | 140GB | 38GB | ❌ 需要 2x 4090 + 量化 |
| Qwen2.5-72B | 144GB | 39GB | ❌ 需要 2x 4090 + 量化 |
| DeepSeek-V3 (671B MoE) | 1342GB | 340GB | ❌ 需要集群 |
# 在 RTX 4090 上用 llama.cpp 部署 Llama-3.1-70B(Q4_K_M 量化)
# 需要 2 张 4090 或 1 张 4090 + 大内存(CPU offload)
# 下载 GGUF 格式模型
huggingface-cli download \
bartowski/Llama-3.1-70B-Instruct-GGUF \
Llama-3.1-70B-Instruct-Q4_K_M.gguf \
--local-dir ./models
# 启动推理服务(2 张 GPU)
./llama-server \
-m ./models/Llama-3.1-70B-Instruct-Q4_K_M.gguf \
--host 0.0.0.0 \
--port 8080 \
-ngl 99 \ # 所有层加载到 GPU
-c 4096 \ # 上下文长度
--n-gpu-layers-m 1 \ # 模型分片到多张 GPU
-np 8 # 并行 slot 数(类似 Continuous Batching)
3.2 多卡/多机部署:vLLM + Tensor Parallelism
当单卡放不下模型时,需要 Tensor Parallelism(张量并行) 将模型切分到多张 GPU:
# vLLM 多卡部署 Llama-3.1-70B(2x A100 80GB)
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 2 \ # 2 张 GPU 做张量并行
--dtype auto \ # 自动选择精度(A100 用 BF16)
--max-model-len 8192 \ # 最大上下文长度
--enable-prefix-caching \ # 启用前缀缓存
--enable-chunked-prefill \ # 分块预填充
--max-num-seqs 32 \ # 最大并发请求
--gpu-memory-utilization 0.92 \ # GPU 显存利用率
--swap-space 4 \ # CPU swap 空间 (GB)
--quantization awq \ # 如果用 AWQ 量化模型
--port 8000
多机部署(Pipeline Parallelism):
# vLLM 多机部署(需要 Ray 集群)
# 节点 1(Head Node)
ray start --head --port=6379
# 节点 2
ray start --address="node1:6379"
# 启动推理(跨 2 台机器,每台 2 张 A100)
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 2 \
--pipeline-parallel-size 2 \ # 跨机器的流水线并行
--distributed-executor-backend ray \
--max-model-len 8192
3.3 MoE 模型的特殊优化
MoE(Mixture of Experts)模型(如 DeepSeek-V3、Mixtral)有独特的优化挑战:Expert Routing 的负载不均衡会导致部分 GPU 过载,其他 GPU 空闲。
# expert_load_balance.py — 监控 Expert 负载均衡
import torch
from collections import defaultdict
class ExpertLoadMonitor:
"""Monitor expert routing distribution in MoE models"""
def __init__(self, num_experts: int):
self.num_experts = num_experts
self.token_counts = torch.zeros(num_experts)
self.step_count = 0
def record_routing(self, expert_indices: torch.Tensor):
"""Record which experts were selected for each token"""
# expert_indices: [batch_size, seq_len, top_k]
flat_indices = expert_indices.flatten()
counts = torch.bincount(flat_indices, minlength=self.num_experts)
self.token_counts += counts.float()
self.step_count += 1
def get_imbalance_ratio(self) -> float:
"""Calculate load imbalance ratio (1.0 = perfectly balanced)"""
avg = self.token_counts.mean()
if avg == 0:
return 0.0
return (self.token_counts.max() / avg).item()
def report(self):
"""Print load distribution report"""
ratio = self.get_imbalance_ratio()
print(f"Expert Load Imbalance Ratio: {ratio:.2f}")
print(f"Ideal: 1.00 | Acceptable: < 1.50 | Problem: > 2.00")
# Show per-expert distribution
total = self.token_counts.sum()
for i in range(self.num_experts):
pct = (self.token_counts[i] / total * 100).item()
bar = "█" * int(pct)
print(f" Expert {i:2d}: {pct:5.1f}% {bar}")
# Usage
monitor = ExpertLoadMonitor(num_experts=8)
# In your inference loop:
# monitor.record_routing(expert_indices)
# if step % 100 == 0:
# monitor.report()
📌 记住: MoE 模型的优化重点不是减少计算量(因为每次只激活部分专家),而是确保 Expert Routing 的负载均衡 和 All-to-All 通信的效率。如果你的 MoE 模型某些 GPU 利用率特别高,大概率是 Expert Routing 不均衡。
3.4 完整优化链路 Checklist
## LLM 推理优化 Checklist
### 第一步:Profiling(必做)
- [ ] 测量基线 tokens/s(单请求 + 批量)
- [ ] 确认瓶颈类型(Memory-Bound / Compute-Bound)
- [ ] 记录 GPU 利用率和显存占用
### 第二步:Batching 优化
- [ ] 启用 Continuous Batching(vLLM/SGLang 默认开启)
- [ ] 调整 max-num-seqs(从 32 开始逐步调大)
- [ ] 启用 Chunked Prefill(长 prompt 场景必开)
### 第三步:Caching 优化
- [ ] 启用 Prefix Caching(多轮对话/RAG 场景)
- [ ] 监控 Cache Hit Rate(目标 > 70%)
- [ ] 调整显存分配给 Cache 的比例
### 第四步:量化
- [ ] 评估质量损失是否可接受
- [ ] H100/A100 优先用 FP8
- [ ] 消费级 GPU 用 AWQ/GPTQ INT4
- [ ] 本地部署用 GGUF Q4_K_M
### 第五步:投机解码(可选)
- [ ] 选择合适的 Draft Model
- [ ] 验证 Acceptance Rate(目标 > 70%)
- [ ] 监控实际加速比
### 第六步:持续监控
- [ ] 监控 TTFT(Time To First Token)
- [ ] 监控 TPS(Tokens Per Second)
- [ ] 监控 P99 延迟
- [ ] 设置 GPU 利用率告警
📊 四、性能基准:不同优化组合的效果对比
以下数据基于 Llama-3.1-70B-Instruct,2x A100 80GB,ShareGPT 负载:
| 优化配置 | Throughput (tokens/s) | TTFT (ms) | P99 Latency (s) | 显存占用 |
|---|---|---|---|---|
| 基线(FP16,默认配置) | 1,200 | 850 | 8.2 | 140GB |
| + Continuous Batching (64) | 4,800 | 920 | 6.5 | 148GB |
| + Prefix Caching | 7,200 | 380 | 4.1 | 152GB |
| + FP8 量化 | 9,600 | 350 | 3.2 | 78GB |
| + Chunked Prefill | 11,500 | 290 | 2.8 | 80GB |
| + 投机解码 (EAGLE) | 14,200 | 280 | 2.1 | 92GB |
⚡ 关键结论: 从基线到全优化,吞吐量提升了 11.8 倍(1,200 → 14,200 tokens/s)。但请注意:这些优化不是简单的叠加关系,某些组合可能有冲突(如投机解码与大 batch size 的收益会递减)。
🛡️ 五、避坑指南:生产环境常见陷阱
5.1 坑 1:max-model-len 设太大导致 OOM
# ❌ 错误:设 32K 上下文,KV Cache 直接爆显存
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-70B-Instruct \
--max-model-len 32768 # 32K 上下文需要 ~80GB KV Cache!
# ✅ 正确:根据实际需求设合理值,留足显存给并发
python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-70B-Instruct \
--max-model-len 4096 \ # 大多数场景 4K 足够
--max-num-seqs 32 # 更多并发 = 更高吞吐
⚠️ 警告: KV Cache 显存 = 2 × num_layers × num_kv_heads × head_dim × max_seq_len × batch_size × bytes_per_element。一个 70B 模型在 32K 上下文下,单请求 KV Cache 就需要约 2.5GB。32 个并发请求就是 80GB——一张 A100 的全部显存。
5.2 坑 2:盲目追求 tokens/s 忽略 TTFT
很多开发者只关注 tokens/s(吞吐量),忽略了 TTFT(首 Token 延迟)。在聊天场景中,用户感知的"快"主要是 TTFT 低,而不是 tokens/s 高。
优化 TTFT 的方法:
- ✅ 启用 Chunked Prefill——将长 prompt 分块处理,不阻塞其他请求
- ✅ 启用 Prefix Caching——跳过重复的 prompt 计算
- ✅ 减小 max-model-len——减少 KV Cache 预分配
5.3 坑 3:量化模型不做质量验证
# quality_check.py — 量化后的质量验证脚本
import json
TEST_CASES = [
{
"prompt": "请解释量子纠缠的原理",
"check_keywords": ["量子", "纠缠", "叠加", "测量"],
"category": "科学知识"
},
{
"prompt": "写一个 Python 快速排序",
"check_keywords": ["def ", "partition", "return", "pivot"],
"category": "代码生成"
},
{
"prompt": "翻译成英文:今天天气真好",
"check_keywords": ["weather", "nice", "today", "good"],
"category": "翻译"
}
]
def validate_quality(model_fn, test_cases, threshold=0.8):
"""Validate model output quality after quantization"""
results = []
for case in test_cases:
output = model_fn(case["prompt"])
matched = sum(1 for kw in case["check_keywords"] if kw in output)
score = matched / len(case["check_keywords"])
results.append({
"category": case["category"],
"score": score,
"pass": score >= threshold
})
status = "✅" if score >= threshold else "❌"
print(f"{status} {case['category']}: {score:.0%}")
total_pass = sum(1 for r in results if r["pass"])
print(f"\nOverall: {total_pass}/{len(results)} passed")
return all(r["pass"] for r in results)
💡 提示: 量化后至少用 20-30 个测试用例验证质量,覆盖你的核心业务场景。不要只看 Perplexity——它不能反映真实任务表现。
5.4 坑 4:Tensor Parallelism 跨 NUMA 节点
在多路 CPU 服务器上,不同 PCIe 插槽可能属于不同的 NUMA 节点。如果 GPU 跨 NUMA 节点做 Tensor Parallelism,CPU-GPU 通信延迟会显著增加。
# 检查 NUMA 拓扑
nvidia-smi topo -m
# 如果看到 GPU 之间没有 NVLink,且跨 NUMA 节点
# 优先选择同一 NUMA 节点内的 GPU
CUDA_VISIBLE_DEVICES=0,1 python -m vllm.entrypoints.openai.api_server \
--model meta-llama/Llama-3.1-70B-Instruct \
--tensor-parallel-size 2
🎯 总结与建议
LLM 推理优化不是某个单一技术的应用,而是一条完整的工程链路。根据你的场景选择合适的优化组合:
| 场景 | 推荐优化组合 | 预期加速 |
|---|---|---|
| 本地开发/测试 | GGUF Q4_K_M + llama.cpp | 基准可用 |
| 单机生产(低并发) | FP8/AWQ + vLLM + Prefix Caching | 3-5x |
| 单机生产(高并发) | FP8 + Continuous Batching + Chunked Prefill | 8-12x |
| 多机集群 | Tensor Parallelism + 投机解码 + 全部优化 | 10-15x |
| MoE 模型 | Expert Parallelism + 负载均衡监控 | 视模型而定 |
优化顺序很重要——先做 Profiling 定位瓶颈,再按优先级逐步优化:
- Continuous Batching(投入产出比最高,几乎所有场景都有效)
- Prefix Caching(多轮对话/RAG 场景效果显著)
- 量化(减少显存占用,但要验证质量)
- 投机解码(降低延迟,但增加复杂度)
- 硬件升级(NVLink、更大显存的 GPU)
⚡ 关键结论: 80% 的性能提升来自前两步(Batching + Caching)。如果你只做一件事,就启用 Continuous Batching 并把 batch size 调到合理值——这一个改动就能让你的 GPU 利用率从 5% 提升到 60% 以上。
相关工具推荐:
- 🔧 vLLM — 生产级 LLM 推理引擎
- 🔧 SGLang — 高性能推理框架,RadixAttention 前缀缓存
- 🔧 llama.cpp — 本地部署首选
- 🔧 TensorRT-LLM — NVIDIA 官方优化引擎
- 🔧 Hermes Agent — 用 AI 助手管理你的推理服务部署