离线推理( offline inference )场景中,比较关注最大化吞吐量并降低单次推理成本。传统方法往往是资源消耗大、速度慢、容易出现性能瓶颈、导致云服务开支较高。需要专为大语言模型优化的推理部署引擎。

下面 LLM 的两种离线推理部署性能对比:vLLM vs HuggingFace.

HuggingFace Transformers

HuggingFace 的 Transformers 库已经是 LLM 领域标准工具,其具有API接口统一、模型库庞大、开箱即用等特性。

离线部署场景,HuggingFace 提供了直观的工作流程:

  • 模型 和 tokenizer 加载
  • 循环或者批量方式,处理输入数据。

但是,其存在明显瓶颈,尤其是在未进行专门优化的情况下:顺序处理机制、相对抵消的内存管理(尤其是注意力的 key 和 value 缓存的管理) 会显著影响性能。

虽然 HuggingFace 的 Transformers 库具有较高的灵活性,但是面对与大规模离线推理场景,会存在效率问题。

典型的推理代码如,

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

MODEL_NAME = "meta-llama/Llama-3.2-3B-Instruct"

# Load model and tokenizer
model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(
    MODEL_NAME,
    padding_side="left",
    truncation_side="left"
)

# Set pad_token (LLaMA doesn't define one by default)
tokenizer.pad_token = tokenizer.eos_token

# Define batch of user prompts (4 in total)
user_questions = [
    "What is Thailand's national food symbol?",
    "What is the capital of Norway?",
    "Who invented the telescope?",
    "What is the chemical symbol for gold?"
]

# Format messages in chat format
messages_batch = [
    [
        {"role": "system", "content": "You are a helpful assistant. Respond in two sentences."},
        {"role": "user", "content": question}
    ]
    for question in user_questions
]

# Tokenize using chat template with padding and truncation
input_ids = tokenizer.apply_chat_template(
    messages_batch,
    tokenize=True,
    return_tensors="pt",
    padding=True,
    truncation=True,
    max_length=2048
).to(model.device)

# Clear previous GPU stats (optional, but good practice for clean runs)
torch.cuda.empty_cache()

# Generate responses
input_length = input_ids.shape[1]
generated_ids = model.generate(
    input_ids=input_ids,
    max_new_tokens=128,
    pad_token_id=tokenizer.pad_token_id
)

# Decode outputs
decoded_outputs = tokenizer.batch_decode(
    generated_ids[:, input_length:],
    skip_special_tokens=True
)

vLLM

vLLM 是专为吞吐量和效率而设计。其核心创新在于PagedAttention技术,该技术能够高效管理注意力中的 key 和 value 对内存。

注意力中的 key 和 value 对内存管理,对于离线推理是至关重要的,因为,键值缓存(KV cache) 会消耗大量的 GPU 显存,尤其是在处理长序列和大批量数据时。PagedAttention创新性的将 KV cache 内存看作是分页(pages),并采用类似于操作系统虚拟内存的机制,实现内存分配和回收。该技术显著减少了内存碎片化,有效提升批量大小。

此外,vLLM 还整合多想创新技术,如,

  • 连续批处理Continuous Batching:实时处理动态请求流,通过即时响应新任务而非等待满批处理,显著提升GPU利用率。该技术通常用在 online serving,但是对于离线部署中处理不同长度的连续提示序列也同样高效。
  • 快速模型执行Fast Model Execution:利用CUDA/HIP计算图技术来优化 kernel 执行。
  • 量化支持 Quantization Support:同 GPTQ、AWQ、INT4、INT8、FP8 等多种量化方案,有效降低显存占用,提升推理速度。
  • 优化的 CUDA内核 Optimized CUDA Kernels:集成 FlashAttention、FlashInfer等高性能Kernels,实现底层运算加速。

灵活性和易用性方面,vLLM 同样具有如下优势:

  • 无缝兼容 HuggingFace 模型
  • 支持多种加码算法,如采样sampling、束搜索beam search等
  • 分部署推理,支持张量并行tensor parallelism 和流水线并行pipeline parallelism
  • 内置 OpenAI-compatible API 服务接口
  • 支持多种硬件,如NVIDIA、AMD、Intel 等,以及专用的AI加速器等

典型的推理代码如,

import torch
from vllm import LLM, SamplingParams
from transformers import AutoTokenizer

# Initialize tokenizer separately to apply chat template
MODEL_NAME = "meta-llama/Llama-3.2-3B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
tokenizer.pad_token = tokenizer.eos_token  # Just in case

# Define a batch of prompts (4 in total)
user_questions = [
    "What is Thailand's national food symbol?",
    "What is the capital of Norway?",
    "Who invented the telescope?",
    "What is the chemical symbol for gold?"
]

# Create structured chat messages
messages_batch = [
    [
        {"role": "system", "content": "You are a helpful assistant. Respond in two sentences."},
        {"role": "user", "content": question}
    ]
    for question in user_questions
]

# Manually apply chat template to each prompt
rendered_prompts = [
    tokenizer.apply_chat_template(messages, tokenize=False)
    for messages in messages_batch
]

# Define generation parameters
sampling_params = SamplingParams(max_tokens=128)

# Initialize vLLM
llm = LLM(
    model=MODEL_NAME,
    max_model_len=2048,
)

# Run batch generation
outputs = llm.generate(rendered_prompts, sampling_params)

性能对比

实验环境:

实现结果:

对比在不同批量大小下的推理耗时,模拟典型离线推理工作负载。如:

Batch SizevLLM IFT(sec)HuggingFace IFT (sec)
42.325.32
82.517.24
163.019.50
323.3812.90

IFT = Inference Time

关键结果:

  • vLLM 在批量任务中,速度是 HuggingFace 的 2-4 倍
  • vLLM 采用 PagedAttention 优化 KV cache 内存
  • vLLM 对于大规模推理具有更好的可扩展性和GPU利用率

总结

  1. vLLM 更适合于生产环境的高吞吐、高性能离线部署
  2. HuggingFace 在算法研究和原型开发中灵活性更好
Last modification:May 24th, 2025 at 10:24 pm