Skip to content

基础概念

什么是大语言模型(LLM)?常见的开源大模型有哪些?

答:大语言模型(Large Language Model, LLM)是基于深度学习的自然语言处理模型,具有数十亿到万亿级参数。常见开源大模型包括:

模型参数量开发者特点
LLaMA 系列7B-70B+Meta开源先驱,生态丰富
Qwen(通义千问)系列0.5B-72B+阿里中英文能力强
DeepSeek 系列1.3B-67B深度求索性价比高
Yi(零一万物)系列6B-34B零一万物中文优化
ChatGLM 系列6B-9B清华/智谱AI中文对话优化
Mistral 系列7B-8x7BMistral AI欧洲代表
BLOOM 系列176BBigScience多语言支持

运行大模型需要哪些基本条件?

硬件要求

模型规模显存需求(FP16)推荐显卡最低配置
7B 模型~14 GBRTX 3090 / A10RTX 4090 (24GB)
13B 模型~26 GBA100 (40GB)2x RTX 3090
33B 模型~66 GBA100 (80GB)2x A100 80GB
70B 模型~140 GB2x A100 80GB4x A100 80GB

软件环境

bash
# CUDA 版本要求
CUDA >= 11.8 (推荐 12.1+)
cuDNN >= 8.6
Python >= 3.8
PyTorch >= 2.0

# 常用推理框架
vLLM、TensorRT-LLM、llama.cpp、Ollama

大模型的量化是什么?常用的量化方法有哪些?

答:量化是将模型权重从高精度(FP32/FP16)转换为低精度(INT8/INT4),以减少显存占用和加速推理:

常用量化方法

方法精度显存节省质量损失
FP1616-bit50%几乎无
INT88-bit75%较小
INT44-bit87.5%有一定损失
GPTQ4-bit87.5%较小
AWQ4-bit87.5%较小
python
# 使用 transformers 进行量化示例
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.float16
)

model = AutoModelForCausalLM.from_pretrained(
    "model_name",
    quantization_config=bnb_config
)

运行时问题排查

大模型出现 OOM(Out of Memory)如何解决?

原因分析

  1. 显存不足:模型参数 + KV Cache 占用超过 GPU 显存
  2. 批次过大:同时处理过多请求
  3. 序列过长:生成长度过长导致 KV Cache 膨胀

解决方案

1. 模型量化

bash
# 使用 vLLM 加载量化模型
vllm serve Qwen/Qwen2.5-7B-Instruct-AWQ \
    --quantization awq \
    --tensor-parallel-size 1

2. 调整推理参数

python
# vLLM 配置优化
from vllm import LLM, SamplingParams

llm = LLM(
    model="model_path",
    max_model_len=2048,        # 限制最大长度
    gpu_memory_utilization=0.9, # GPU 内存使用率
    swap_space=4,              # 使用 CPU 内存作为交换空间(GB)
    enforce_eager=False,       # 启用 CUDA Graph 优化
)

3. 分布式推理(张量并行)

bash
# 多卡张量并行
vllm serve model_name \
    --tensor-parallel-size 4 \   # 使用 4 张 GPU
    --max-model-len 8192

4. 卸载策略

python
# CPU Offload - 将部分层卸载到 CPU
from accelerate import init_empty_weights
from transformers import AutoConfig, AutoModelForCausalLM

config = AutoConfig.from_pretrained("model_name")
with init_empty_weights():
    model = AutoModelForCausalLM.from_config(config)

# 使用 device_map 自动分配
model = AutoModelForCausalLM.from_pretrained(
    "model_name",
    device_map="auto",          # 自动分配设备
    max_memory={0: "20GiB", "cpu": "60GiB"}  # 指定各设备内存上限
)

大模型越用越卡的原因及解决方案?

原因分析

1. KV Cache 无限增长

解决方案

python
# 设置合理的 max_num_seqs 和上下文限制
llm = LLM(
    model="model_path",
    max_num_seqs=256,           # 最大并发请求数
    max_model_len=8192,         # 最大序列长度
)

2. GPU 内存碎片化

现象:长时间运行后可用显存减少但无法分配

解决方案

  • 定期重启服务或使用 PagedAttention
  • 启用内存整理机制

3. 连接池耗尽

yaml
# Nginx 或 API Gateway 配置优化
upstream llm_backend {
    server 127.0.0.1:8000;
    keepalive 64;              # 保持连接数
    keepalive_timeout 300s;    # 连接超时时间
    keepalive_requests 10000;  # 单连接最大请求数
}

4. 磁盘 I/O 瓶颈(使用 swap 时)

解决方案

  • 增加 SSD 作为交换分区
  • 减少 swap 使用,增加 GPU 数量
  • 使用 NVMe 存储

5. Python GC 问题

python
# 定期手动触发垃圾回收
import gc
import torch

def cleanup():
    gc.collect()
    torch.cuda.empty_cache()
    torch.cuda.reset_peak_memory_stats()

# 在请求处理间隔调用
cleanup()

Kubernetes 运行大模型

Kubernetes 运行大模型有哪些方案?

方案对比

方案适用场景优点缺点
原生 Deployment小模型(≤7B)简单易用无 GPU 调度优化
Volcano批量训练/推理支持 Gang 调度配置复杂
KubeRay分布式推理Ray 集成好学习成本高
Kaito大规模部署微软出品,自动化依赖 Azure
Kserve/Serving生产级 Serving自动扩缩容配置复杂

Kubernetes GPU 调度插件原理?

1. NVIDIA Device Plugin

工作原理

  1. 设备发现:NVIDIA Device Plugin 在节点上运行,检测所有 NVIDIA GPU
  2. 资源注册:将 GPU 注册为 nvidia.com/gpu 扩展资源
  3. 资源上报:通过 gRPC 向 Kubelet 上报可用 GPU 数量
  4. 调度决策:Kubernetes Scheduler 根据资源请求进行调度
  5. 设备分配:Pod 创建时,Device Plugin 选择并分配具体 GPU
yaml
# Pod 使用 GPU 示例
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  containers:
  - name: inference
    image: vllm/vllm-openai:latest
    resources:
      limits:
        nvidia.com/gpu: 1  # 请求 1 个 GPU
    env:
    - name: CUDA_VISIBLE_DEVICES
      value: "0"

2. GPU Sharing(MIG / Time-slicing)

MIG(Multi-Instance GPU)

yaml
# 使用 MIG 分区
apiVersion: v1
kind: Pod
metadata:
  name: mig-pod
spec:
  containers:
  - name: inference
    image: vllm/vllm-openai:latest
    resources:
      limits:
        nvidia.com/mig-1g.5gb: 1  # 请求 MIG 实例

时间分片(Time-Slicing)

yaml
# ConfigMap 配置 GPU 共享
apiVersion: v1
kind: ConfigMap
metadata:
  name: nvidia-device-plugin-configs
  namespace: kube-system
data:
  staus: |-
    version: v1
    sharing:
      timeSlicing:
        renameByDefault: false
        failRequestsGreaterThanOne: true
        resources:
        - name: nvidia.com/gpu
          replicas: 4  # 每个 GPU 分成 4 个虚拟 GPU

3. Volcano 调度器

Volcano 是专门为高性能计算设计的批处理调度器:

yaml
# Volcano Job 示例
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
  name: llm-inference
spec:
  schedulerName: volcano
  minAvailable: 1
  tasks:
  - replicas: 1
    template:
      spec:
        containers:
        - name: inference
          image: vllm/vllm-openai:latest
          resources:
            requests:
              nvidia.com/gpu: 4
            limits:
              nvidia.com/gpu: 4
  policies:
  - event: PodEvicted
    action: RestartJob

Gang Scheduling 机制

  • 所有 Pod 同时启动或全部不启动
  • 避免"部分就绪"导致的死锁
  • 对分布式大模型推理至关重要

如何在 Kubernetes 中实现大模型的自动扩缩容?

基于 KPA/KEDA 的扩缩容

yaml
# KEDA Scaler 示例
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: llm-scaler
spec:
  scaleTargetRef:
    name: llm-deployment
  minReplicaCount: 1
  maxReplicaCount: 10
  cooldownPeriod: 300
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus.monitoring:9090
      metricName: request_queue_length
      threshold: "100"
      query: avg(request_queue_length)

自定义指标扩缩容

python
# 自定义 Metrics Adapter
class LLMMetricsAdapter:
    def get_metric(self):
        return {
            "gpu_utilization": self.get_gpu_usage(),
            "request_latency_p99": self.get_p99_latency(),
            "queue_depth": self.get_queue_size(),
            "tokens_per_second": self.get_tps()
        }

推理框架

常见的大模型推理框架有哪些?如何选择?

框架特点适用场景性能
vLLMPagedAttention,高吞吐生产部署★★★★★
TensorRT-LLMNVIDIA 优化,极致性能NVIDIA GPU★★★★★
llama.cppCPU/GPU 通用,量化友好本地/边缘设备★★★★☆
Ollama简单易用,一键部署个人开发测试★★★☆☆
SGlang结构化输出,复杂编排Agent 应用★★★★☆
Text Generation InferenceHuggingFace 出品HF 生态集成★★★★☆

vLLM 的 PagedAttention 原理是什么?

答:PagedAttention 是 vLLM 的核心创新,灵感来自操作系统的虚拟内存分页:

核心优势

  1. 内存效率提升 2-4 倍:按需分配而非预分配
  2. 支持更高并发:相同显存可服务更多用户
  3. 减少 OOM 风险:动态调整内存使用

TensorRT-LLM 的优化原理?

答:TensorRT-LLM 是 NVIDIA 提供的高性能推理引擎:

主要优化技术

技术说明效果
Fusion融合多个算子为一个 kernel减少显存访问
KV Cache 优化in-place 更新、页锁定降低延迟
量化支持INT8/INT4/FP8提升吞吐量
Inflight Batching动态批处理高效利用 GPU
Parallel Attention并行注意力计算加速推理
bash
# 构建 TensorRT-LLM 引擎
trtllm-build --model_dir ./model_checkpoint \
             --output_dir ./engine \
             --dtype float16 \
             --max_batch_size 32 \
             --max_input_len 1024 \
             --max_output_len 512

监控与运维

大模型服务需要监控哪些关键指标?

基础设施层

指标说明告警阈值建议
GPU 利用率GPU 计算负载>90% 持续 5 分钟
GPU 显存使用率显存占用情况>95%
GPU 温度硬件温度>85°C
GPU 功耗功率消耗接近 TDP 上限
NVLink 带宽利用率多卡通信带宽>80%

应用层

指标说明告警阈值建议
请求延迟 P50/P99响应时间分布P99 > 10s
Tokens Per Second (TPS)生成速度< 20 tokens/s
请求队列长度等待处理的请求数> 100
错误率失败请求比例> 1%
Time To First Token (TTFT)首字延迟> 2s

使用 Prometheus + Grafana 监控

yaml
# DCGM Exporter 部署
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: dcgm-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: dcgm-exporter
  template:
    metadata:
      labels:
        app: dcgm-exporter
    spec:
      containers:
      - name: dcgm-exporter
        image: nvcr.io/nvidia/k8s/dcgm-exporter:3.3.1-3.1.8-ubuntu22.04
        ports:
        - containerPort: 9400
          name: metrics
        securityContext:
          runAsNonRoot: false
          capabilities:
            add: ["SYS_ADMIN"]
        volumeMounts:
        - name: proc-mount
          mountPath: /proc
          readOnly: true
      volumes:
      - name: proc-mount
        hostPath:
          path: /proc

如何对大模型服务进行日志收集和分析?

关键日志信息

json
{
  "timestamp": "2024-01-15T10:30:00Z",
  "request_id": "req-123456",
  "model": "Qwen2.5-7B-Instruct",
  "input_tokens": 150,
  "output_tokens": 500,
  "latency_ms": 2500,
  "ttft_ms": 200,
  "tps": 200.0,
  "status": "success",
  "error": null
}

日志收集架构

安全与成本优化

大模型服务的安全注意事项有哪些?

1. API 安全

nginx
# 速率限制
limit_req_zone $binary_remote_addr zone=llm_limit:10m rate=10r/s;

server {
    location /v1/chat/completions {
        limit_req zone=llm_limit burst=20;
        
        # 请求体大小限制
        client_max_body_size 100k;
        
        # 超时设置
        proxy_read_timeout 120s;
        
        proxy_pass http://llm_backend;
    }
}

2. 内容安全

  • 输入过滤:Prompt Injection 检测
  • 输出过滤:敏感内容过滤
  • PII 保护:个人信息脱敏
  • 访问控制:基于角色的权限管理

3. 模型安全

  • 模型文件加密:防止模型被窃取
  • API Key 管理:定期轮换密钥
  • 审计日志:记录所有访问和操作

如何降低大模型服务的运营成本?

成本优化策略

策略说明预计节省
模型量化INT4/INT8 量化显存成本降低 50-75%
动态扩缩容按需调整实例数量30-50%
批量推理合并请求提高吞吐20-40%
缓存策略缓存相似查询结果10-30%
Spot 实例使用竞价实例60-70%
模型选择根据任务选合适规模变化较大

缓存策略实现

python
# 语义缓存示例
from sentence_transformers import SentenceTransformer
import hashlib
import redis

class SemanticCache:
    def __init__(self):
        self.encoder = SentenceTransformer('all-MiniLM-L6-v2')
        self.redis = redis.Redis(host='localhost', port=6379)
        self.threshold = 0.95  # 相似度阈值
    
    def get(self, query: str):
        query_embedding = self.encoder.encode(query)
        
        # 查找相似的缓存条目
        for key in self.redis.scan_iter("cache:*"):
            cached_embedding = self.redis.hget(key, "embedding")
            similarity = cosine_similarity(query_embedding, cached_embedding)
            
            if similarity > self.threshold:
                return self.redis.hget(key, "response")
        
        return None
    
    def set(self, query: str, response: str):
        key = f"cache:{hashlib.md5(query.encode()).hexdigest()}"
        embedding = self.encoder.encode(query)
        
        self.redis.hset(key, mapping={
            "response": response,
            "embedding": embedding.tobytes(),
            "query": query
        })
        self.redis.expire(key, 3600)  # 1小时过期

故障排查实战

排查大模型服务响应慢的完整流程

常用排查命令

bash
# 查看 GPU 状态
nvidia-smi
watch -n 1 nvidia-smi

# 查看 GPU 详细指标
dcgmi profile -e

# 查看 NVLink 状态
nvidia-smi nvlink --status

# 查看进程 GPU 使用情况
nvidia-smi pmon

# 查看 Docker 容器 GPU 使用
docker stats --format "table {{.Name}}\t{{.GPUMemoryUsage}}"