☰
week9
2026/10/4 17:19:24 网站建设 项目流程

目标:
部署一个VLLM大模型服务,验证速度提升。

内容:

使用同一个开源大模型,分别采用 Hugging Face Transformers 原生推理和 vLLM 服务化推理,在相同硬件、相同输入长度、相同输出长度下,对比单请求延迟、并发吞吐、TTFT、TPOT 和 Tokens/s,验证 vLLM 在在线推理场景中的性能提升。


一、第九周作业目标

本周重点掌握 5 个知识点:

  1. 学会下载并运行一个开源大语言模型。
  2. 使用 Hugging Face Transformers 实现基线推理。
  3. 使用 vLLM 部署 OpenAI Compatible API 服务。
  4. 学会进行并发压测。
  5. 对比不同推理框架下的延迟和吞吐量。

最终实验结构:

同一个模型 │ ├── Hugging Face Transformers │ ↓ │ 普通推理基线 │ └── vLLM ↓ OpenAI API Server ↓ Benchmark ↓ 延迟 / Tokens/s / 吞吐量

二、为什么要学习 vLLM?

前面的课程重点基本都是模型训练,例如:

RNN LSTM Transformer 文本分类 序列标注 文本匹配

但真正把大模型应用到线上,还会遇到:

模型推理太慢 GPU 利用率不高 并发能力差 显存容易浪费

比如直接使用 Transformers:

model.generate(...)

一两个请求问题不大,但如果线上同时来了 10、50、100 个请求,如何高效利用 GPU 就变得非常重要。

vLLM 的定位就是:

面向大语言模型的高吞吐推理和服务框架。


三、实验整体设计

建议选择一个能在本机 GPU 上稳定运行的模型。

如果使用 RTX 4060 Laptop GPU 这类显卡,显存通常会成为主要约束,因此建议优先使用:

Qwen/Qwen2.5-1.5B-Instruct

如果显存更充足,可以考虑:

Qwen 3B / 4B 7B 量化模型

为了保证实验公平,最重要的是:

基线和 vLLM 必须使用同一个模型。

四、实验环境建议

项目配置
OSUbuntu 22.04 / Linux
GPURTX 4060 Laptop GPU
CUDA按实际环境填写
Python3.10 / 3.11
PyTorch按实际版本填写
vLLM按实际版本填写
Transformers按实际版本填写
ModelQwen2.5-1.5B-Instruct
dtypefloat16 / auto
输入长度约 128 tokens
最大输出128 tokens
Benchmark Requests100 / 500
并发1 / 4 / 8 / 16

如果实验机是 Windows,建议使用:

WSL2 + Ubuntu

或者直接 Linux。


五、项目结构

week9/ ├── baseline_transformers.py ├── test_vllm.py ├── benchmark_client.py ├── requirements.txt ├── results/ │ ├── baseline.json │ ├── vllm_concurrency_1.json │ ├── vllm_concurrency_4.json │ ├── vllm_concurrency_8.json │ └── vllm_concurrency_16.json └── SUMMARY.md

六、第一步:检查 GPU 环境

先执行:

nvidia-smi

重点查看:

GPU 型号 CUDA Version 显存大小 显存占用

然后 Python 中检查:

importtorchprint("CUDA available:",torch.cuda.is_available())print("CUDA version:",torch.version.cuda)iftorch.cuda.is_available():print("GPU:",torch.cuda.get_device_name(0))

七、安装环境

建议创建独立虚拟环境:

conda create-nweek9-vllmpython=3.11-yconda activate week9-vllm

安装:

pipinstallvllm pipinstalltransformers accelerate openai

查看版本:

python-c"import torch; print(torch.__version__)"python-c"import vllm; print(vllm.__version__)"python-c"import transformers; print(transformers.__version__)"

八、实验一:Transformers 原生推理基线

创建:

baseline_transformers.py

代码:

importtimeimporttorchfromtransformersimportAutoTokenizer,AutoModelForCausalLM MODEL_NAME="Qwen/Qwen2.5-1.5B-Instruct"device="cuda"tokenizer=AutoTokenizer.from_pretrained(MODEL_NAME)model=AutoModelForCausalLM.from_pretrained(MODEL_NAME,torch_dtype=torch.float16,device_map=device)model.eval()prompt="请简单介绍一下 Transformer 模型的工作原理。"messages=[{"role":"user","content":prompt}]text=tokenizer.apply_chat_template(messages,tokenize=False,add_generation_prompt=True)inputs=tokenizer(text,return_tensors="pt").to(device)# Warmupwithtorch.no_grad():_=model.generate(**inputs,max_new_tokens=32)torch.cuda.synchronize()start=time.perf_counter()withtorch.no_grad():outputs=model.generate(**inputs,max_new_tokens=128,do_sample=False)torch.cuda.synchronize()elapsed=time.perf_counter()-start input_tokens=inputs.input_ids.shape[1]output_tokens=outputs.shape[1]-input_tokens tokens_per_second=output_tokens/elapsedprint("="*50)print("Input tokens:",input_tokens)print("Output tokens:",output_tokens)print(f"Latency:{elapsed:.3f}s")print(f"Generation speed:{tokens_per_second:.2f}token/s")result=tokenizer.decode(outputs[0][input_tokens:],skip_special_tokens=True)print("\nResult:")print(result)

运行:

python baseline_transformers.py

注意:作业报告必须填写自己实际测试的数据。


九、为什么一定要 Warmup?

第一次推理通常包含:

CUDA 初始化 Kernel 初始化 内存分配 模型缓存

因此第一次调用:

model.generate()

通常不能直接作为最终性能数据。

正确流程:

Warmup ↓ 正式 Benchmark

十、实验二:启动 vLLM 服务

启动:

vllm serve Qwen/Qwen2.5-1.5B-Instruct

或者:

vllm serve\Qwen/Qwen2.5-1.5B-Instruct\--host0.0.0.0\--port8000

默认服务地址:

http://localhost:8000

十一、验证服务是否启动成功

首先:

curlhttp://localhost:8000/v1/models

然后测试 Chat Completions:

curlhttp://localhost:8000/v1/chat/completions\-H"Content-Type: application/json"\-d'{ "model": "Qwen/Qwen2.5-1.5B-Instruct", "messages": [ { "role": "user", "content": "请简单介绍Transformer。" } ], "temperature": 0, "max_tokens": 128 }'

十二、使用 Python 调 vLLM 服务

创建:

test_vllm.py
importtimefromopenaiimportOpenAI client=OpenAI(base_url="http://localhost:8000/v1",api_key="EMPTY")start=time.perf_counter()response=client.chat.completions.create(model="Qwen/Qwen2.5-1.5B-Instruct",messages=[{"role":"user","content":"请简单介绍一下 Transformer 模型。"}],temperature=0,max_tokens=128)elapsed=time.perf_counter()-start usage=response.usageprint("Prompt tokens:",usage.prompt_tokens)print("Completion tokens:",usage.completion_tokens)print(f"Latency:{elapsed:.3f}s")speed=usage.completion_tokens/elapsedprint(f"Output speed:{speed:.2f}token/s")print("\nResult:")print(response.choices[0].message.content)

运行:

python test_vllm.py

十三、只测一个请求,可能看不出 vLLM 的优势

如果 Transformers 和 vLLM 都只跑 1 个请求,你可能发现差异并不明显。

vLLM 真正需要重点验证的是:

并发请求下的整体吞吐量。

因此建议测试:

1 并发 4 并发 8 并发 16 并发

十四、核心实验:并发性能测试

实验并发
Test 11
Test 24
Test 38
Test 416
Test 532(显存允许时)

每次建议:

100 个 Prompt input ≈ 128 tokens output = 128 tokens

十五、自己写并发 Benchmark

创建:

benchmark_client.py
importasyncioimporttimeimportstatisticsfromopenaiimportAsyncOpenAI MODEL="Qwen/Qwen2.5-1.5B-Instruct"client=AsyncOpenAI(base_url="http://localhost:8000/v1",api_key="EMPTY")PROMPT="请解释 Transformer 中 Self-Attention 的基本工作原理。"asyncdefrequest_once():start=time.perf_counter()response=awaitclient.chat.completions.create(model=MODEL,messages=[{"role":"user","content":PROMPT}],max_tokens=128,temperature=0)elapsed=time.perf_counter()-start output_tokens=response.usage.completion_tokensreturnelapsed,output_tokensasyncdefworker(semaphore):asyncwithsemaphore:returnawaitrequest_once()asyncdefbenchmark(total_requests,concurrency):semaphore=asyncio.Semaphore(concurrency)start=time.perf_counter()tasks=[worker(semaphore)for_inrange(total_requests)]results=awaitasyncio.gather(*tasks)total_time=time.perf_counter()-start latencies=[x[0]forxinresults]total_tokens=sum(x[1]forxinresults)throughput=total_tokens/total_time request_per_second=total_requests/total_timeprint("\n=============================")print("Concurrency:",concurrency)print("Requests:",total_requests)print(f"Total time:{total_time:.2f}s")print(f"RPS:{request_per_second:.2f}")print(f"Output throughput:{throughput:.2f}token/s")print(f"Average latency:{statistics.mean(latencies):.2f}s")print(f"P50 latency:{statistics.median(latencies):.2f}s")print(f"Max latency:{max(latencies):.2f}s")asyncdefmain():forconcurrencyin[1,4,8,16]:awaitbenchmark(total_requests=100,concurrency=concurrency)asyncio.run(main())

运行:

python benchmark_client.py

十六、推荐:直接使用 vLLM 官方 Benchmark

可以查看:

vllm bench serve--help

通过官方 benchmark 工具,可以更标准地测试:

模型 数据集 输入长度 输出长度 请求数量 请求速率 并发吞吐

十七、真正应该关注哪些指标?

1. TTFT

Time To First Token

即:

用户发送请求到看到第一个 Token 的时间。

这个指标直接影响用户对“响应快不快”的感知。

2. TPOT

Time Per Output Token

表示第一个 Token 出来以后,平均生成一个 Token 需要多少时间。

例如:

TPOT = 30 ms

大致相当于:

≈ 33 token/s

3. End-to-End Latency

完整请求耗时:

请求开始 ↓ Prompt Prefill ↓ Decode ↓ 生成结束

4. Throughput

这是验证 vLLM 优势的核心指标。

计算:

Speedup = vLLM Throughput / Baseline Throughput

最终应该报告:

Speedup = X.XX ×

必须来自实际测试结果。


十八、为什么 vLLM 吞吐通常会提升?

1. KV Cache

Transformer 在生成过程中,过去 Token 的 Key / Value 可以缓存下来,避免重复计算。

随着:

上下文长度 ↑ 并发用户 ↑

KV Cache 的显存需求也会快速增大。

2. PagedAttention

可以将 KV Cache 的管理方式类比操作系统分页:

虚拟内存 ↓ Page ↓ 按页管理

相比为每个请求预留连续空间,分页方式可以更加灵活地利用 GPU 显存。

3. Continuous Batching

假设三个请求:

A:生成 20 token B:生成 200 token C:生成 50 token

当 A 完成后,可以及时将新请求加入,而不是等待整个固定 Batch 都结束。

因此在并发场景中:

GPU 利用率 ↑ 吞吐量 ↑

十九、不要把“速度提升”简单理解为单请求更快

更准确的结论是:

vLLM 的主要优势通常体现在大模型在线 Serving 的 GPU 利用率、并发调度和总体吞吐能力上;具体单请求延迟是否改善,以及吞吐可以提高多少,需要结合模型、GPU、输入输出长度、并发量和配置通过实测确定。


二十、实验时一定要控制变量

必须保持:

同一个模型 同一个 GPU 同一个 dtype 相同 Prompt 相同输入长度 相同输出长度 相同 temperature

例如:

Model: Qwen2.5-1.5B-Instruct temperature: 0 max_tokens: 128

二十一、推荐测试矩阵

建议至少完成:

Transformers ├── concurrency 1 ├── concurrency 4 ├── concurrency 8 └── concurrency 16 vLLM ├── concurrency 1 ├── concurrency 4 ├── concurrency 8 └── concurrency 16

形成:

2 个推理框架 × 4 个并发级别 = 8 组实验

每组建议:

Warmup 10 正式测试 100

二十二、建议最终实验结果表

单请求测试

FrameworkLatencyOutput TokensTokens/s
Transformers实测128实测
vLLM实测128实测

并发吞吐测试

并发TransformersvLLMSpeedup
1实测实测x
4实测实测x
8实测实测x
16实测实测x

单位统一:

output tokens / second

二十三、建议额外记录 GPU 数据

压测时开另一个终端:

watch-n1nvidia-smi

记录:

FrameworkGPU UtilGPU Memory
Transformers实测实测
vLLM实测实测

这样可以进一步验证:

性能提升是否来自更高的 GPU 利用率

二十四、第九周最终实验结论模板

## 实验结论 本实验尝试将开源大语言模型部署为在线推理服务, 并比较 Hugging Face Transformers 与 vLLM 在相同模型和硬件条件下的推理性能。 实验重点考察单请求延迟、TTFT、TPOT、 Output Tokens/s、Requests/s 以及不同并发条件下的吞吐量。 单请求场景下,两种方案的性能差异需要结合实际测试结果分析。 随着并发请求数量增加,vLLM 可以通过更高效的 KV Cache 管理、PagedAttention 与 Continuous Batching 提升 GPU 利用率和整体吞吐能力。 本实验说明,大模型推理系统不能只关注模型本身, 还需要关注推理框架、并发调度、显存管理以及服务吞吐量。

二十五、本周进阶实验

实验一:不同并发数

1 2 4 8 16 32

绘制:

Concurrency → Tokens/s

曲线,观察 GPU 最大吞吐点。

实验二:不同输入长度

128 512 1024 2048

观察:

TTFT 显存 Throughput

变化。

实验三:不同输出长度

32 128 512

观察 Decode 阶段对性能的影响。


二十六、第九周作业验收标准

建议至少完成:

  1. 成功启动一个 vLLM 大模型服务。
  2. /v1/chat/completions能正常返回结果。
  3. 完成 Transformers 原生推理基线。
  4. 测试并发1 / 4 / 8 / 16。
  5. 记录单请求延迟。
  6. 记录 Requests/s。
  7. 记录 Output Tokens/s。
  8. 最好记录 TTFT / TPOT。
  9. 对比 GPU 显存和利用率。
  10. 计算实际 Speedup:
vLLM Throughput ---------------- Baseline Throughput

最终得到:

Speedup = X.XX ×

总结

第九周最核心的知识点不是“把模型跑起来”,而是理解为什么同一个大模型,在不同推理框架和不同并发条件下,会表现出完全不同的服务能力。

通过本次实验,可以进一步理解:

大模型部署 ↓ 推理服务 ↓ KV Cache ↓ PagedAttention ↓ Continuous Batching ↓ 并发压测 ↓ 吞吐优化

这也为后续学习大模型分布式推理、Tensor Parallel、多 GPU 部署和生产级 LLM Serving 打下基础。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询