Qwen3.5-27B部署流程

环境准备

创建体验空间

在魔乐社区的体验空间创建需要部署的环境
image.png

注:这里我选的是二卡,大家如果需要部署更大的模型可以使用到更高的卡,需要使用到多卡的请联系魔乐社区的相关人员

选择完配置后,我们点击创建,构建完成之后点击中间的“点击打开空间应用”就可以进入了

image.png

image.png

然后我们就进入,点击Terminal打开终端

image.png

模型权重和环境包下载

我们先把模型权重下载好

# 首先保证已安装git-lfs(https://git-lfs.com)
git lfs install
git clone https://modelers.cn/Qwen-AI/Qwen3.5-27B.git

image.png

下载完权重之后我们再把部署需要的环境包也拉一下,这里是我自己打包好的环境,现在社区的体验空间是没有办法访问外网的,所以我这里是在自己电脑上将环境打包之后上传到社区,然后在从社区拉到空间中,大家有其他更好的方法也可以用其他的方法

# 首先保证已安装git-lfs(https://git-lfs.com)
git lfs install
git clone https://modelers.cn/chicheng/Qwen3.5-huanj.git

image.png

然后我们把环境包移动出来

# 使用mv移动到根目录就行
mv 文件名 /home/openmind(要移动的目录)

image.png

部署环境

然后我们需要创建一个新的环境来部署我们的模型,这里我用的是miniconda,大家也可以使用其他的

首先我们需要清除当前shell会话中的PYTHONPATH环境变量,清除它可以避免与CANN、MindSpore等框架的预配置环境冲突。

#清除当前shell会话中的PYTHONPATH环境变量
unset PYTHONPATH

注意这个命令操作只影响当前终端会话,重新打开终端或新会话会恢复原来的PYTHONPATH设置,需要重新再执行一次。

执行完以上命令之后我们就可以安装miniconda,创建python3.11环境

# 安装miniconda
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh
bash Miniconda3-latest-Linux-aarch64.sh
conda config --set auto_activate_base false
bash

image.png

image.png

#加载conda配置
source ~/.bashrc
# 接受main通道的条款
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main
# 接受r通道的条款  
conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r
# 创建python3.11环境
conda create --name ais_bench python=3.11 -y
conda activate ais_bench

image.png

image.png

解压环境包

tar -xzf vllm-pr34521.tar.gz
tar -xzf vllm-ascend-pr6742.tar.gz
tar -xzf transformers-fc91372.tar.gz

image.png

安装环境

# 安装 transformers
cd transformers
pip install .
cd ..

# 安装 vllm
cd vllm
VLLM_TARGET_DEVICE=empty pip install -v .
cd ..

image.png

image.png

安装vllm-ascend特殊一点因为我之前是在 Windows 环境打包的环境,导致行尾格式为 CRLF(\r\n),而 Linux 下需要 LF(\n)。

所以我们需要处理一下

cd vllm-ascend
sed -i 's/\r$//' csrc/build_aclnn.sh
find csrc -name "*.sh" -exec sed -i 's/\r$//' {} \;
export SOC_VERSION=ascend910b2
pip install -v .

image.png

之后我们可以使用pip list向下拉查看到vllm和vllm-ascend的版本

image.png

部署模型

完成环境的搭建之后我们还需要将昇腾的环境启动命令跑一遍,使用以下的命令

source /usr/local/Ascend/ascend-toolkit/set_env.sh
source /usr/local/Ascend/nnal/asdsip/set_env.sh
source /usr/local/Ascend/nnal/atb/set_env.sh

运行完上面的命令之后,我们就可以进行模型的部署了,使用下面的命令用vllm部署模型

export PYTORCH_NPU_ALLOC_CONF="expandable_segments:True"
export HCCL_OP_EXPANSION_MODE="AIV"
export HCCL_BUFFSIZE=1024
export OMP_NUM_THREADS=1
export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOAD
export TASK_QUEUE_ENABLE=1

vllm serve /home/openmind/Qwen3.5-27B/ \
    --served-model-name "qwen3.5" \
    --host 0.0.0.0 \
    --port 8010 \
    --data-parallel-size 1 \
    --tensor-parallel-size 2 \
    --gpu-memory-utilization 0.94 \
    --max-model-len 5000 \
    --max-num-batched-tokens 16384 \
    --max-num-seqs 128 \
    --trust-remote-code \
    --reasoning-parser qwen3 \
    --async-scheduling \
    --allowed-local-media-path / \
    --mm-processor-cache-gb 0 \
    --enforce-eager \
    --additional-config '{"enable_cpu_binding":true, "multistream_overlap_shared_expert": true}'

image.png

image.png

上面这样就是部署成功了,接下来我们新开一个终端使用curl进行简单的对话测试

curl -s http://localhost:8010/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3.5",
    "messages": [{"role": "user", "content": "你是谁?请使用中文回答"}],
    "max_tokens": 1000
  }' | jq -r '.choices[0].message.content' | awk '/<\/think>/{flag=1; next} flag' | sed '/^$/d'

在服务端我们可以看到

image.png

客户端输出

image.png

到这里说明我们就部署成功了
然后我们也可以使用代码的形式实现多轮对话

#!/usr/bin/env python3
import requests
import json
import re

API_URL = "http://localhost:8010/v1/chat/completions"
HEADERS = {"Content-Type": "application/json"}
MODEL = "qwen3.5"

def extract_answer(text):
    """提取最终答案,确保返回非空字符串"""
    think_end = text.find('</think>')
    if think_end != -1:
        after_think = text[think_end + 8:].strip()
        if after_think:
            return after_think
    matches = re.findall(r'[“"]([^”"]+)[”"]', text)
    if matches:
        return matches[-1].strip()
    lines = text.split('\n')
    non_empty = [line.strip() for line in lines if line.strip() and not line.startswith(('Thinking', 'Step', '1.', '2.'))]
    if non_empty:
        return non_empty[-1]
    return text.strip() or "[模型未返回有效内容]"

def chat():
    messages = [
        {"role": "system", "content": "你是一个直接回答的助手。请只输出最终答案,不要包含任何分析、思考过程或额外解释。"}
    ]
    print("多轮对话已启动(输入 'exit' 或 'quit' 退出)")
    while True:
        user_input = input("\n你: ").strip()
        if user_input.lower() in ("exit", "quit"):
            break
        if not user_input:
            continue

        messages.append({"role": "user", "content": user_input})
        payload = {
            "model": MODEL,
            "messages": messages,
            "max_tokens": 1000
        }

        try:
            response = requests.post(API_URL, headers=HEADERS, json=payload)
            response.raise_for_status()
            data = response.json()
            full_content = data["choices"][0]["message"]["content"]
            answer = extract_answer(full_content)
            if answer:
                print(f"\n助手: {answer}")
                messages.append({"role": "assistant", "content": answer})
            else:
                print("\n助手: [模型未生成有效回答]")
                messages.pop()  # 移除用户消息,避免历史污染
        except Exception as e:
            print(f"请求失败: {e}")
            messages.pop()  # 移除用户消息
if __name__ == "__main__":
    chat()

在这里插入图片描述

至此部署的内容就到此为止了,大家如果是对模型做了适配的,也欢迎大家把适配好的模型上传至魔乐社区。

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐