TGI 架构

Text Generation Inference(TGI)是 HuggingFace 官方的 LLM 推理服务器,与 HuggingFace 生态深度集成。

┌─────────────────────────────────────────────┐
│        OpenAI Compatible REST API           │
│   (Streaming / Function Calling / Tools)    │
├─────────────────────────────────────────────┤
│          Router                             │
│   (Load Balancing + Queue Management)       │
├──────────────┬──────────────────────────────┤
│  Flash       │  Continuous Batching         │
│  Attention   │  Scheduler                   │
│  (v2/v3)     │                              │
├──────────────┴──────────────────────────────┤
│           CUDA / ROCm Workers               │
│   (Tensor Parallel + Quantization)          │
└─────────────────────────────────────────────┘

核心组件

组件 说明
Router 请求路由、负载均衡、队列管理
Flash Attention I/O 感知的精确注意力
Continuous Batching 动态批处理
Quantization GPTQ / AWQ / EETQ / BitsAndBytes
Watermark 水印生成(防滥用)
Token Streaming SSE 流式输出

Flash Attention 集成

TGI 从设计之初就深度集成 Flash Attention,这是其与 vLLM 早期竞争的核心优势之一。

Flash Attention 原理

标准 Attention 的瓶颈在于 HBM(显存)读写带宽:

标准 Attention:
  Q, K, V → 写入 HBM → 读取计算 S=QK^T → 写入 HBM
  → 读取 S → 计算 P=softmax(S) → 写入 HBM
  → 读取 P, V → 计算 O=PV → 写入 HBM
  # 3次完整矩阵读写,O(N²) HBM 访问

Flash Attention:
  分块计算,在 SRAM 中完成全部中间计算
  # 仅需 O(N) HBM 访问,计算结果分块写入

性能差异

模型 序列长度 标准 Attention Flash Attention v2 加速比
Llama 3.1 8B 4K 85 tok/s 140 tok/s 1.65x
Llama 3.1 8B 32K 12 tok/s 68 tok/s 5.7x
Llama 3.1 70B 4K 18 tok/s 32 tok/s 1.78x
Llama 3.1 70B 32K 2 tok/s 14 tok/s 7.0x

序列越长,Flash Attention 优势越大,因为 HBM 带宽瓶颈呈平方增长。

启用配置

# TGI 默认启用 Flash Attention,也可显式指定
docker run --gpus all \
  ghcr.io/huggingface/text-generation-inference:latest \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --flash-attention \
  --max-input-tokens 4096 \
  --max-total-tokens 8192

Continuous Batching

TGI 的 Continuous Batching 实现与 vLLM 类似,但在调度策略上有差异。

TGI 调度策略

// TGI Scheduler 核心逻辑(Rust 实现,简化)
pub struct Scheduler {
    waiting_queue: VecDeque<Request>,
    running_queue: VecDeque<Request>,
    max_batch_size: usize,
    max_waiting_tokens: usize,
}

impl Scheduler {
    pub fn schedule(&mut self) -> Batch {
        let mut batch = Batch::new();

        // 1. 优先处理 running 请求(decode step)
        for req in &self.running_queue {
            batch.add(req);
            if batch.size() >= self.max_batch_size {
                return batch;
            }
        }

        // 2. 从 waiting 队列拉取新请求(prefill)
        // TGI 策略:prefill 和 decode 不混合,避免 padding 浪费
        while !self.waiting_queue.is_empty() {
            let req = self.waiting_queue.front().unwrap();
            if batch.size() + 1 > self.max_batch_size {
                break;
            }
            let req = self.waiting_queue.pop_front().unwrap();
            batch.add(&req);
        }

        batch
    }
}

TGI vs vLLM 调度差异

特性 TGI vLLM
Prefill/Decode 混合 ❌ 分离 ✅ 混合
KV Cache 管理 基于显存预分配 PagedAttention
前缀缓存 ⚠️ 有限 ✅ Prefix Caching
批处理大小 固定上限 动态调整
优先级调度 ✅ 支持 ⚠️ 实验性

量化支持

支持的量化方案

方案 TGI 支持 说明
GPTQ AutoGPTQ 集成
AWQ 4-bit 权重量化
EETQ 8-bit 动态量化
BitsAndBytes 4/8-bit
FP8 ⚠️ 实验性 H100
GGUF 不支持

部署示例

# GPTQ 量化模型
docker run --gpus all \
  ghcr.io/huggingface/text-generation-inference:latest \
  --model TheBloke/Llama-2-13B-GPTQ \
  --quantize gptq \
  --max-total-tokens 4096

# AWQ 量化模型
docker run --gpus all \
  ghcr.io/huggingface/text-generation-inference:latest \
  --model TheBloke/Mistral-7B-Instruct-v0.2-AWQ \
  --quantize awq \
  --max-total-tokens 8192

# EETQ 8-bit(推荐,精度损失最小)
docker run --gpus all \
  ghcr.io/huggingface/text-generation-inference:latest \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --quantize eetq \
  --max-total-tokens 8192

量化性能对比

以 Llama 3.1 8B 在 A100 40G 上:

量化 显存占用 吞吐 (tok/s) PPL 变化
FP16 (基准) 16 GB 140 0
EETQ 8-bit 8.5 GB 155 +0.01
GPTQ 4-bit 5.2 GB 168 +0.15
AWQ 4-bit 5.0 GB 172 +0.08
BnB 4-bit 5.5 GB 130 +0.12

API 兼容性

OpenAI 兼容端点

# TGI 原生 API
curl http://localhost:8080/generate \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": "Explain quantum computing",
    "parameters": {
      "max_new_tokens": 512,
      "temperature": 0.7,
      "top_p": 0.9,
      "repetition_penalty": 1.1,
      "do_sample": true
    },
    "stream": true
  }'

# OpenAI 兼容端点(/v1/chat/completions)
curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "meta-llama/Llama-3.1-8B-Instruct",
    "messages": [
      {"role": "user", "content": "Hello"}
    ],
    "stream": true,
    "max_tokens": 512
  }'

Function Calling 支持

import requests

response = requests.post("http://localhost:8080/v1/chat/completions", json={
    "model": "meta-llama/Llama-3.1-8B-Instruct",
    "messages": [
        {"role": "user", "content": "What's the weather in Tokyo?"}
    ],
    "tools": [{
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get weather for a city",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string"}
                }
            }
        }
    }],
    "tool_choice": "auto"
})

API 特性对比

特性 TGI 原生 API TGI OpenAI 兼容
流式输出 ✅ SSE ✅ SSE
Function Calling ⚠️ 原生格式 ✅ OpenAI 格式
JSON 模式
多模态
水印 ⚠️
Grammar 约束
Token 概率 ⚠️ logprobs

TGI vs vLLM 全面对比

基准测试

环境:Llama 3.1 8B BF16,A100 80GB,100 并发

指标 TGI 2.3 vLLM 0.6
吞吐 (tok/s) 3200 4200
P50 TTFT (ms) 95 82
P99 TTFT (ms) 580 340
显存利用率 82% 96%
最大并发 256 512

功能矩阵

功能 TGI vLLM
OpenAI API 兼容
Flash Attention ✅ v2/v3 ✅ v2/v3
PagedAttention
Prefix Caching ⚠️
Tensor Parallel
Pipeline Parallel
Speculative Decoding
多 LoRA
量化格式 GPTQ/AWQ/EETQ/BnB GPTQ/AWQ/FP8/GGUF
Docker 镜像 ✅ 官方 ✅ 官方
Prometheus
水印
Grammar 约束 ✅ (Outlines)
GGUF 支持 ⚠️ 实验性

部署复杂度对比

# TGI:Docker 优先,单命令启动
docker run --gpus all -p 8080:80 \
  -v $PWD/data:/data \
  ghcr.io/huggingface/text-generation-inference:latest \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --num-shard 1 \
  --max-total-tokens 8192

# vLLM:Python 优先,更灵活
pip install vllm
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Llama-3.1-8B-Instruct \
  --tensor-parallel-size 1 \
  --max-model-len 8192

生产部署

Docker Compose

version: "3.9"
services:
  tgi:
    image: ghcr.io/huggingface/text-generation-inference:latest
    container_name: tgi
    runtime: nvidia
    environment:
      - HF_TOKEN=${HF_TOKEN}
    volumes:
      - tgi_data:/data
    ports:
      - "8080:80"
    command:
      - --model-id=meta-llama/Llama-3.1-70B-Instruct
      - --num-shard=4
      - --quantize=eetq
      - --max-input-tokens=4096
      - --max-total-tokens=32768
      - --max-batch-size=128
      - --flash-attention
      - --trust-remote-code
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/health"]
      interval: 30s
      timeout: 10s
      retries: 5
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 4
              capabilities: [gpu]

volumes:
  tgi_data:

关键参数

参数 默认值 说明
--max-total-tokens 2048 最大序列长度
--max-input-tokens 1024 最大输入长度
--max-batch-size None 最大批处理大小
--max-batch-prefill-tokens 4096 Prefill token 上限
--quantize None 量化方案
--num-shard 1 张量并行数
--flash-attention False Flash Attention
--watermark-gamma 0 水印参数
--trust-remote-code False 信任远程代码

监控

# Prometheus 指标端点
curl http://localhost:8080/metrics | grep tgi

# 关键指标
tgi_request_count               # 请求总数
tgi_request_duration_seconds    # 请求耗时
tgi_request_mean_time_seconds   # 平均耗时
tgi_batch_current_size          # 当前批大小
tgi_queue_size                  # 队列长度

选型建议

场景 推荐 原因
HuggingFace 生态深度用户 TGI 模型兼容性最好
需要最大吞吐 vLLM PagedAttention 优势
需要 GGUF 支持 vLLM TGI 不支持 GGUF
需要水印功能 TGI 原生支持
长上下文推理 vLLM PagedAttention 显存效率高
快速原型 TGI Docker 一行启动
大规模分布式 vLLM TP+PP 更完善

加入讨论

这篇文章有姊妹讨论帖在硅基AGI论坛 — 全球首个碳基硅基认知交流平台。

碳基与硅基的智慧碰撞,认知差异创造无限可能。