1.下载权重和环境安装
python
from modelscope import snapshot_download
model_dir = snapshot_download('Qwen/QwQ-32B-AWQ', cache_dir='/root/autodl-tmp', revision='master')
pip安装vllm版本
python
pip install modelscope==1.22.3
pip install openai==1.61.0
pip install tqdm==4.67.1
pip install transformers==4.48.2
pip install vllm==0.7.1
pip install streamlit==1.41.1
2.vllm 启动serve
shell
python -m vllm.entrypoints.openai.api_server \
--model /root/autodl-tmp/Qwen/QwQ-32B-AWQ \
--served-model-name QwQ-32B-AWQ \
--quantization awq \
--api-key token-abc123 \
--tensor-parallel-size 1 \
--max-model-len 4096 \
--port 8000 \
--gpu-memory-utilization 0.98 # 可能需要提高
2.1 curl 测试
curl -H "Authorization: Bearer token-abc123" http://localhost:8000/v1/models
返回结果如下:
json
{"object":"list","data":[{"id":"QwQ-32B-AWQ","object":"model","created":1741542802,"owned_by":"vllm","root":"/root/autodl-tmp/Qwen/QwQ-32B-AWQ","parent":null,"max_model_len":4096,"permission":[{"id":"modelperm-35e17fea1e8049de84303e133a981c48","object":"model_permission","created":1741542802,"allow_create_engine":false,"allow_sampling":true,"allow_logprobs":true,"allow_search_indices":false,"allow_view":true,"allow_fine_tuning":false,"organization":"*","group":null,"is_blocking":false}]}]}
2.2 curl 测试个问题
json
curl http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer token-abc123" \
-d '{
"model": "QwQ-32B-AWQ",
"prompt": "《红楼梦》第五回中警幻仙姑请贾宝玉欣赏的红楼十二支曲子的名字都叫什么?<think>\n",
"max_tokens": 1024,
"temperature": 0
}'
返回结果如下:
json
{"id":"cmpl-6c0c56d0a88b4b7781133a01c002bbf0","object":"text_completion","created":1741543078,"model":"QwQ-32B-AWQ","choices":[{"index":0,"text":"《红楼梦》第五回中,警幻仙姑请贾宝玉欣赏的红楼十二支曲子的名字分别是:\n\n1. 《红楼梦》\n2. 《枉凝眉》\n3. 《葬花吟》\n4. 《分骨肉》\n5. 《乐中悲》\n6. 《世难容》\n7. 《喜冤家》\n8. 《虚花悟》\n9. 《聪明累》\n10. 《留余庆》\n11. 《晚韶华》\n12. 《好事终》\n\n这些曲子分别预示了小说中主要人物的命运和结局,是《红楼梦》的重要组成部分。","logprobs":null,"finish_reason":"stop","stop_reason":null,"prompt_logprobs":null}],"usage":{"prompt_tokens":28,"total_tokens":183,"completion_tokens":155,"prompt_tokens_details":null}}
3. streamlit启动web页面
使用命令 streamlit run app.py --server.port 6006
启动后运行结果和后台日志图如下,AWQ后不太适合复杂场景问题。
后台日志
修改了下app.py 具体如下:
python
import streamlit as st
import requests
import re
# 在侧边栏中创建一个标题和一个链接
with st.sidebar:
st.markdown("## QwQ-32B LLM")
"[开源大模型食用指南 self-llm](https://github.com/datawhalechina/self-llm.git)"
# 创建一个滑块,用于选择最大长度,范围在 0 到 2048 之间,默认值为 1024
max_length = st.slider("max_length", 0, 2048, 1024, step=1)
# 创建一个标题和一个副标题
st.title("💬 QwQ-32B Chatbot")
st.caption("🚀 A streamlit chatbot powered by Self-LLM")
def split_text(text):
"""
分割生成的文本,提取思考过程和回答内容。
Args:
text (str): 生成的文本。
Returns:
tuple: (思考过程, 回答内容)
"""
# 定义正则表达式模式,匹配 <think>思考过程</think>回答
pattern = re.compile(r'<think>(.*?)</think>(.*)', re.DOTALL)
match = pattern.search(text)
if match: # 如果匹配到思考过程
think_content = match.group(1).strip() # 获取思考过程
answer_content = match.group(2).strip() # 获取回答
else:
think_content = "" # 如果没有匹配到思考过程,则设置为空字符串
answer_content = text.strip() # 直接返回回答
return think_content, answer_content
# 初始化 session_state 中的消息列表
if "messages" not in st.session_state:
st.session_state["messages"] = [{"role": "assistant", "content": "有什么可以帮您的?"}]
# 遍历 session_state 中的所有消息,并显示在聊天界面上
for msg in st.session_state.messages:
st.chat_message(msg["role"]).write(msg["content"])
# 如果用户在聊天输入框中输入了内容,则执行以下操作
if prompt := st.chat_input():
# 在聊天界面上显示用户的输入
st.chat_message("user").write(prompt)
# 将用户输入添加到 session_state 中的 messages 列表中
st.session_state.messages.append({"role": "user", "content": prompt})
# 调用本地运行的 vLLM 服务
try:
headers = {
"Authorization": f"Bearer token-abc123",
"Content-Type": "application/json"
}
response = requests.post(
"http://localhost:8000/v1/chat/completions",
headers=headers, # 添加请求头
json={
"model": "QwQ-32B-AWQ",
"messages": st.session_state.messages,
"max_tokens": max_length
}
)
if response.status_code == 200:
response_data = response.json()
assistant_response = response_data["choices"][0]["message"]["content"]
# 分割思考过程和回答内容
think_content, answer_content = split_text(assistant_response)
# 将模型的输出添加到 session_state 中的 messages 列表中
st.session_state.messages.append({"role": "assistant", "content": assistant_response})
# 在聊天界面上显示模型的输出
with st.expander("模型思考过程"):
st.write(think_content) # 展示模型思考过程
st.chat_message("assistant").write(answer_content) # 输出模型回答
else:
st.error("Error generating response.")
except Exception as e:
st.error(f"An error occurred: {e}")