最近考虑测试一下南北阁的SLM Nanbeige4.1-3B,手头正好有一块24G显存的RTX 3090显卡。话不多说,首先配置一下环境:
bash
# conda create -n nanbeige python=3.12
# conda activate nanbeige
# export PYTHONNOUSERSITE=1
# pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 根据你的CUDA版本调整
# pip install transformers accelerate sentencepiece
# pip install -U "huggingface_hub[cli]"
# pip install vllm # 作为LLM后端
# pip install gradio # 作为LLM promt前端
然后通过Python脚本downlod.py进行Nanbeige4.1-3B模型权重下载:
python
from huggingface_hub import snapshot_download
import huggingface_hub
# 1. 强制开启 INFO 级别的日志,确保所有下载状态和进度条都不被终端隐藏
huggingface_hub.utils.logging.set_verbosity_info()
print("开始下载 Nanbeige4.1-3B...")
snapshot_download(
repo_id="Nanbeige/Nanbeige4.1-3B",
local_dir="./Nanbeige4.1-3B",
resume_download=True,
max_workers=8
)
print("下载完成!")
运行python downlod.py后,将在本地创建"./Nanbeige4.1-3B"路径下载模型权重。
在用vLLM加载模型前,让我们创建一个gradio前端web_demo_vllm.py:
python
import os
import gradio as gr
from openai import OpenAI
import re
client = OpenAI(
api_key="EMPTY",
base_url="http://localhost:8000/v1"
)
def predict(message, history):
messages = [
{"role": "system", "content": "你是一个极其高效、精简的AI助手。请尽量缩短 <think> 思考过程,不要写长篇大论的推导,直接给出精准、简明的最终答案。"}
]
for item in history:
role = item.get("role")
content = item.get("content", "")
# 如果是模型说的话,用正则把思考过程删掉,只把最终答案发给下一轮
#print("content: ",content)
if role == "assistant":
content[0]["text"] = re.sub(r'<think>.*?</think>', '', content[1]["text"], flags=re.DOTALL).strip()
messages.append({"role": role, "content": content})
print("messages: ", messages)
# 加入当前用户的最新提问
messages.append({"role": "user", "content": message})
try:
response = client.chat.completions.create(
model="./Nanbeige4.1-3B",
messages=messages,
max_tokens=30000,
temperature=0.4,
top_p=0.95,
stream=True
)
partial_message = ""
for chunk in response:
# 提取每一个新生成的 token
if chunk.choices[0].delta.content is not None:
partial_message += chunk.choices[0].delta.content
yield partial_message
except Exception as e:
yield f"⚠️ 请求失败,请检查终端中的 vLLM 服务是否正常运行。错误信息: {str(e)}"
# 启动聊天界面
demo = gr.ChatInterface(
predict,
title="Nanbeige4.1-3B 🚀 ",
description="南北阁测试",
)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", server_port=7860)
最后启动模型前后端,首先终端1开启vLLM后端:
bash
# python -m vllm.entrypoints.openai.api_server \
--model ./Nanbeige4.1-3B \
--trust-remote-code \
--max-model-len 32768 \
--gpu-memory-utilization 0.8 \
--enforce-eager
上述运行参数的解释如下:
|------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| --trust-remote-code | 允许执行模型文件夹中自带的自定义 Python 代码。很多像 Nanbeige 这样最新的国产开源模型,其内部的网络架构(如特殊的注意力机制)还没有被 Hugging Face 的标准库官方收录。它们会在文件夹里自带一段写好的 Python 代码。加上这个参数,就是给系统开绿灯:"我信任这个模型,允许你运行它自带的底层代码来构建神经网络。"(如果不加,模型通常会加载失败)。 |
| --max-model-len | 设定本次服务允许的最大上下文窗口长度(单位:Token)。 这是模型的"记忆容量上限"(大约相当于 2.5 万到 3 万个汉字)。24G的显存足够支撑 32K,意味着模型现在可以一口气吞下一篇中篇小说或者几十页的 PDF,而不会因为超出长度而报错。但同时,这也会让它在启动时申请更大的显存空间来存放 KV Cache。 |
| --gpu-memory-utilization 0.8 | 设置 vLLM 可征用的 GPU 显存比例。0.8 意味着告诉 vLLM:"不管显卡有多大,你最多只能霸占其中 80% 的空间用来放模型权重和 KV Cache,剩下的 20% 必须空出来,留给系统后台、PyTorch 的临时计算和其他突发情况。" 这能有效防止显存被完全榨干导致进程崩溃。 |
| --enforce-eager | 强制使用 PyTorch 的 Eager 模式(动态图模式)执行,禁用 CUDA Graph 编译。默认情况下,vLLM 为了追求极致的毫秒级速度,会在启动时花很长时间"录制"显卡的计算步骤(CUDA Graph),这个过程极其吃显存。代价: 牺牲了大约 5% 的极限并发吞吐量。收益: 启动速度直接起飞(省去了十几秒的编译时间),且彻底根绝了 CUDA 图录制时的显存溢出风险,非常适合我们这种在本地单卡上做测试和开发的场景。 |
[vLLM参数解释]
最后启动终端2运行gradio前端:
bash
# python web_demo_vllm.py
* Running on local URL: http://0.0.0.0:7860
* To create a public link, set `share=True` in `launch()`.
最后访问llm前端,就可以开启本地的智能体开发了。
