手把手教你部署QWQ模型,开启高效推理之旅

在大语言模型蓬勃发展的当下,掌握模型的本地部署与调用技术,对于开发者深入探索模型性能、实现个性化应用至关重要。本文将以QWQ-32B模型为例,详细阐述其部署与调用的全流程,为大家提供一份全面且具有实操性的技术指南。

一、QWQ-32B模型探秘

QWQ-32B是Qwen系列中专注于推理能力的大模型。与传统的指令微调模型不同,它具备思考与推理的能力,这使其在处理复杂下游任务时优势显著,性能可与当前先进的推理模型如DeepSeek-R1和o1-mini相媲美。

该模型通过大规模强化学习进行训练,在初始阶段针对数学和编程任务开展强化学习训练,通过校验数学答案正确性以及评估代码是否通过测试用例来提供反馈。随着训练轮次推进,性能持续提升。之后增加针对通用能力的强化学习,使用通用奖励模型和基于规则的验证器,在提升通用能力的同时,保持数学和编程任务的性能稳定。

其基本参数方面,QwQ 32B属于因果语言模型,经历了预训练、监督微调以及强化学习等训练阶段。采用基于Transformer的架构,运用RoPE位置编码、SwiGLU激活函数、RMSNorm归一化和Attention QKV偏置技术。总参数量达325亿,非嵌入层参数量为310亿,拥有64层网络,采用GQA机制,查询头数为40,键值头数为8,完整支持131,072个token。

在模型思考打印效果方面,需确保输出以“\n”开头,若使用apply_chat_template并设置add_generation_prompt=True,虽可能导致最终回复缺少标签,但属于正常现象。

二、全量模型下载与Transformers推理流程

(一)模型下载与环境搭建

首先,创建虚拟环境,这一步是为了隔离项目的依赖环境,避免不同项目之间的依赖冲突。使用conda命令创建名为QWQ的虚拟环境,指定Python版本为3.11:

conda create --name QWQ python=3.11
conda init
source ~/.bashrc
conda activate QWQ

接着,创建Jupyter Kernel,这能让我们在Jupyter环境中方便地使用该虚拟环境:

conda install jupyterlab
conda install ipykernel
python -m ipykernel install --user --name QWQ --display-name "Python QWQ"

然后,安装魔搭社区工具,魔搭社区为我们提供了丰富的模型资源和工具支持:

pip install modelscope

之后,创建项目主目录并进入该目录:

cd /root/autodl-tmp
mkdir QWQ-32B
cd QWQ-32B

上传项目依赖文件,并安装依赖:

pip install -r requirements.txt

最后,下载项目权重,使用modelscope download命令从指定模型库下载QWQ-32B模型权重到本地目录:

modelscope download --model Qwen/QwQ-32B --local_dir ./QwQ-32B

(二)Jupyter中使用transformer原生库调用流程

在Jupyter中进行模型调用,首先导入相关库:

from modelscope import AutoModelForCausalLM, AutoTokenizer

设置模型下载地址:

model_name = "./QWQ-32B"

实例化预训练模型与分词器:

model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype="auto",
    device_map="auto",
    low_cpu_mem_usage=True
)
tokenizer = AutoTokenizer.from_pretrained(model_name)

创建消息:

prompt = "在单词\"strawberry\"中,总共有几个R?"
messages = [
    {
    
    "role": "user", "content": prompt}
]

进行词嵌入过程:

text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(model.device)

创建并回复:

generated_ids = model.generate(
    **model_inputs,
    max_new_tokens=32768
)
generated_ids = [
    output_ids[len(input_ids):] for input_ids, output_ids in
    zip(model_inputs.input_ids, generated_ids)
]
response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
print(response)

最终运行结果展示了模型的思考过程,从确认单词拼写,到逐个字母分析,最终得出答案,同时还包含了对答案准确性的思考和验证过程。这种思维链的展示有助于我们深入了解模型的推理逻辑。而实际使用中,可通过正则化方法将思维链内容和模型回复内容进行区分。此时模型显存占用约61G。

技术解读:在这一流程中,torch_dtype="auto"会根据硬件自动选择合适的张量数据类型,以优化计算性能;device_map="auto"能自动将模型分配到合适的计算设备上,提高运行效率;low_cpu_mem_usage=True则是为了降低CPU内存的使用,避免内存占用过高导致系统卡顿。

三、模型接入Ollama与推理流程

(一)ollama安装

ollama是一款强大的大模型管理和推理工具,支持多种操作系统。安装方式有在线安装和离线安装两种。
在线安装:在Linux系统中,可使用如下命令快速安装:

curl -fsSL https://ollama.com/install.sh | sh

但由于国内网络环境的限制,下载过程可能不稳定。

离线安装:推荐使用此方法,可在Ollama Github主页查看支持的各操作系统安装包,如Ubuntu操作系统可选择ollama-linux-amd64.tgz下载。也可从课件网盘中下载相关安装包,下载完成后上传至服务器,然后进行解压缩:

mkdir ./ollama
tar -zxvf ollama-linux-amd64.tgz -C ./ollama

解压缩后,在bin目录中可找到ollama命令的可执行文件。若显示没有可执行权限,需使用如下命令添加权限:

chmod +x ollama

为了使用方便,将脚本文件写入环境变量。在主目录下找到.bashrc文件,在文件结尾写入ollama/bin文件路径:

export PATH=$PATH:/root/autodl-tmp/ollama/bin

保存并退出后,使环境变量生效:

source ~/.bashrc

测试ollama环境变量是否生效:

ollama help

(二)QWQ-32B GGUF格式模型权重下载

ollama模型权重下载有两种方案。
方案一:在线下载模型权重,使用pull命令即可直接下载并自动完成注册:

ollama pull qwq

需注意,在使用pull命令前,要先启动ollama。

方案二:离线下载模型权重,从魔搭社区或huggingface下载GGUF格式的权重,例如下载Q4_K_M量化版本:

cd ~/autodl-tmp
mkdir QwQ-32B-GGUF
modelscope download --model Qwen/QwQ-32B-GGUF qwq-32b-q4_k_m.gguf --local_dir ./QwQ-32B-GGUF

下载后,创建一个file文件用于模型注册,在文件中写入自定义模型GGUF权重地址:

FROM ./qwq-32b-q4_k_m.gguf

将该模型加入Ollama本地模型列表:

cd /root/autodl-tmp/QwQ-32B-GGUF
ollama create qwq-32b -f ModelFile

查看模型是否注册成功:

ollama list

(三)ollama API本地运行流程

在部署完ollama之后,可借助ollama API在代码环境中调用模型。
导入OpenAI库:

from openai import OpenAI

实例化OpenAI客户端:

client = OpenAI(
    base_url='http://localhost:11434/v1/',
    api_key='ollama' # required but ignored
)

创建消息:

prompt = "在单词\"strawberry\"中,总共有几个R?"
messages = [
    {
    
    "role": "user", "content": prompt}
]

获得回复:

response = client.chat.completions.create(
    messages=messages,
    model='qwq-32b',
)
print(response.choices[0].message.content)

最终运行结果同样展示了模型对问题的思考和推理过程,从不同角度分析单词中“R”的数量,最后得出正确答案。此时显存占用约22G左右。

深度见解:ollama的优势在于其简洁高效的模型管理和推理能力,通过兼容OpenAI API,降低了开发者接入模型的门槛。同时,其对GGUF格式模型的支持,使得模型的存储和传输更加便捷,适合在资源受限的环境中部署。但在使用手动下载的GGUF格式模型权重时,可能会出现与ollama不兼容的情况,导致模型输出异常,因此优先推荐使用ollama官方的GGUF格式权重。

四、模型接入vLLM与推理流程

(一)vLLM安装与启动

vLLM更适合企业级高并发应用场景,但显存占用较高。安装vLLM:

pip install vllm

目前vLLM已支持QWQ模型调用,启动vLLM时,需根据模型上下文长度和运行GPU数量谨慎设置参数。
32K上下文,单GPU运行命令:

cd /root/autodl-tmp
vllm serve ./QwQ-32B --max-model-len 32768

128K上下文,双GPU运行命令:

cd /root/autodl-tmp
CUDA_VISIBLE_DEVICES=0,1 vllm serve ./QwQ-32B --tensor-parallel-size 2

启动后,后端会显示相关运行信息。

(二)OpenAI风格API响应模式

在Jupyter中使用OpenAI风格API调用vLLM部署的模型。
导入OpenAI库:

from openai import OpenAI

实例化OpenAI客户端:

openai_api_key = "EMPTY"
openai_api_base = "http://localhost:8000/v1"
client = OpenAI(
    api_key=openai_api_key,
    base_url=openai_api_base,
)

创建消息:

prompt = "在单词\"strawberry\"中,总共有几个R?"
messages = [
    {
    
    "role": "user", "content": prompt}
]

获得回复:

response = client.chat.completions.create(
    model="./QwQ-32B",
    messages=messages,
)
print(response.choices[0].message.content)

最终运行结果展示了模型的推理过程,从回忆单词拼写,到分析字母位置,逐步得出答案。

技术解读:vLLM通过优化的内核和内存管理技术,实现了高效的推理性能。在多GPU部署时,--tensor-parallel-size参数用于指定并行的GPU数量,提高计算效率。但随着模型上下文长度的增加,显存占用也会显著提高,在实际应用中需要根据硬件资源进行合理配置。

五、基于llama.cpp的QwQ模型CPU推理

(一)llama.cpp下载与编译

llama.cpp项目允许我们在CPU或CPU+GPU环境下运行模型。首先下载与编译项目。
下载依赖:

apt-get update
apt-get install build-essential cmake curl libcurl4-openssl-dev -y

这些依赖分别用于安装构建必需的工具和库、CMake构建系统、cURL网络工具以及libcurl库的开发版本,以支持项目的构建和网络请求功能。

下载llama.cpp源码,可使用git克隆项目:

git clone https://github.com/ggml-org/llama.cpp

也可从课件网盘中找到代码文件上传服务器并解压缩。

项目构建与编译:

cmake llama.cpp -B llama.cpp/build \
    -DBUILD_SHARED_LIBS=OFF -DGGML_CUDA=ON -DLLAMA_CURL=ON
cmake --build llama.cpp/build --config Release -j --clean-first --target \
    llama-quantize llama-cli llama-gguf-split

在构建命令中,-DBUILD_SHARED_LIBS=OFF指定生成静态库,-DGGML_CUDA=ON启用CUDA支持(若有GPU),-DLLAMA_CURL=ON启用CURL库支持。--config Release指定构建为发布版本,优化性能;-j表示并行构建,加快编译速度;--clean-first在构建前清理之前的构建结果,避免编译错误;--target指定构建特定的目标,如模型量化、命令行工具和模型文件拆分工具。

复制可执行文件:

cp llama.cpp/build/bin/llama-* llama.cpp

(二)借助llama.cpp运行QwQ模型

纯CPU推理流程:

cd ./llama.cpp
./llama-cli \
    --model /root/autodl-tmp/QwQ-32B-GGUF/qwq-32b-q4_k_m.gguf \
    --cache-type-k q4_0 \
    --threads 64 \
    --prio 2 \
    --temp 0.6 \
    --ctx-size 512 \
    --seed 3407 \
    --n-gpu-layers 0 \
    -no-cnv \
    --prompt "<|User|>你好,好久不见,请介绍下你自己。<|Assistant|>"

此时系统只调用内存和CPU进行计算,不会用到GPU,在调用Q4_K_M模型时,实际内存占用为18G,运行速度较慢,约1token/s。

CPU+GPU混合推理:

./llama-cli \
    --model /root/autodl-tmp/QwQ-32B-GGUF/qwq-32b-q4_k_m.gguf \
    --cache-type-k q4_0 \
    --threads 64 \
    --prio 2 \
    --temp 0.6 \
    --ctx-size 512 \
    --seed 3407 \
    --n-gpu-layers 30 \
    -no-cnv \
    --prompt "<|User|>你好,好久不见,请介绍下你自己。<|Assistant|>"

通过设置--n-gpu-layers参数,将部分层加载到GPU上运行,此时显存占用不到10G,推理速度有所提升,能达到接近2tokens/s。

纯GPU推理:

./llama-cli \
    --model /root/autodl-tmp/QwQ-32B-GGUF/qwq-32b-q4_k_m.gguf \
    --cache-type-k q4_0 \
    --threads 64 \
    --prio 2 \
    --temp 0.6 \
    --ctx-size 512 \
    --seed 3407 \
    --n-gpu-layers 64 \
    -no-cnv \
    --prompt "<|User|>你好,好久不见,请介绍下你自己。<|Assistant|>"

将全部模型权重放在GPU上推理,此时GPU占用约18G,推理速度能达到14tokens/s。

深度见解:llama.cpp为我们提供了灵活的推理方式,可根据硬件资源选择合适的推理模式。纯CPU推理适合在没有GPU的设备上运行,但速度较慢;CPU+GPU混合推理在一定程度上平衡了速度和资源占用;纯GPU推理则能充分发挥GPU的性能,实现快速推理。在实际应用中,可根据任务需求和硬件条件灵活切换推理模式。

六、QWQ-32B接入Open-WebUI流程

(一)Open-WebUI部署流程

Open-WebUI是一个可扩展、功能丰富且用户友好的自托管AI平台,支持多种模型运行器。安装Open-WebUI可使用pip命令:

pip install open-webui

也可从GitHub项目主页下载完整代码包,上传至服务器解压缩运行,还可在课件网盘中领取完整代码包进行安装。

(二)Open-WebUI启动与对话流程

在确保ollama正常运行的情况下,启动Open-WebUI。首先设置离线环境,避免启动时自动进行模型下载:

export HF_HUB_OFFLINE=1

然后启动Open-WebUI:

open-webui serve

若启动时报错显示无法下载模型,是因为Open-WebUI试图从huggingface上下载embedding模型,后续可手动将其切换为本地运行的Embedding模型。

在本地浏览器输入地址(如8080端口)即可访问Open-WebUI。若使用AutoDL,则需要使用SSH隧道工具进行地址代理。首次使用前,