QwQ 32B AWQ实践记录

阿里QwQ-32B推理模型本地部署教程

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}")
相关推荐
Baihai_IDP3 小时前
为什么说JSON不一定是LLM结构化输出的最佳选择?
人工智能·llm·aigc
量子位20 小时前
稚晖君机器人 “葡萄缝针” 神技再现江湖,这次是人形的!骑自行车惊呆众人:又抽象又硬核
人工智能·机器人·llm
RWKV元始智能20 小时前
RWKV7-G1 0.1B 推理模型发布,最适合嵌入式的纯血 RNN 模型
人工智能·开源·llm
bastgia21 小时前
TokenSkip:让大模型「跳步骤」推理,速度翻倍
人工智能·机器学习·llm
Pitayafruit1 天前
🤔 Manus值得追捧吗?通过开源方案实测引发的思考
llm·aigc·workflow
余俊晖1 天前
Phi-4-multimodal:图、文、音频统一的多模态大模型架构、训练方法、数据细节
llm·多模态
掘金安东尼1 天前
llm落地困境破局?工作流如何成为程序员的「场景化改造」利器
人工智能·llm
一个热爱生活的普通人1 天前
如何用golang实现一个MCP Server
llm·go·mcp
beolus2 天前
DeepSeek-R1-Distill-Qwen-1.5B基于MindIE推理实践
llm