文档首页/ AI开发平台ModelArts/ 快速入门/ Notebook入门:一键部署Qwen3-8B模型并搭建聊天机器人
更新时间:2026-02-07 GMT+08:00
分享

Notebook入门:一键部署Qwen3-8B模型并搭建聊天机器人

操作场景

对于AI开发者而言,传统的本地开发环境由于资源限制和工具链不完善,导致在进行AI模型的部署和测试时效率低下。例如,当尝试部署Qwen3-8B模型时,本地环境可能无法提供足够的计算资源,也无法支持高效的模型调试和测试。如何在不增加成本的情况下提高AI模型的开发效率?ModelArts开发环境通过云原生的资源使用和开发工具链的集成,旨在解决这些问题,为用户提供更优质的云化AI开发体验。本文聚焦于Qwen3-8B模型的本地高效部署,基于华为昇腾NPU环境,使用vLLM-Ascend推理引擎推理API服务。通过JupyterLab集成调试,展示从模型加载到RESTful接口调用的完整流程,最后通过Gradio组件来生成Chatbot类型的前端UI展示,快速搭建一个聊天机器人。

本案例执行时间大约为20分钟。

相关概念

vLLM-Ascend

vLLM-Ascend是一个关键的硬件适配插件,旨在将大型语言模型(LLM)框架vLLM高效地引入华为Ascend NPU(神经网络处理单元)生态系统。它充当了vLLM核心逻辑与华为NPU硬件之间的桥梁,通过解耦的方式,实现了vLLM的核心优化技术(例如PagedAttention内存管理、连续批处理、快速量化等)在Ascend平台上的无缝对接与高效执行。

Qwen3-8B

Qwen3-8B是阿里巴巴在2025年推出的Qwen3系列中的旗舰开源语言模型,以其出色的性能和高效的资源利用率成为行业标杆。该模型拥有82亿参数,在多项基准测试中表现优异。

前提条件

已完成华为云账号注册、实名认证及相关权限授权。具体操作,请参见一、前置准备:账号与权限

约束限制

本案例仅支持西南-贵阳一区域。控制台界面为新版样式。

计费说明

在ModelArts开发环境中运行Notebook实例时,会使用计算资源和存储资源,产生计算资源和存储资源的累计值计费。计费详情请参见开发环境计费项

步骤一:快速创建/运行Notebook实例

  1. 登录ModelArts管理控制台,在左侧导航栏选择“快速入门”
  2. “开发实践”页签,单击“基于vllm-ascend部署Qwen3-8B并搭建聊天机器人.ipynb”卡片中的“开发”,按需选择“在已有 Notebook 中打开”“新建 Notebook”
    图1 打开已有/创建Notebook实例
    • 在已有Notebook中打开

      如果您之前已经创建了Notebook,单击“在已有 Notebook 中打开”,系统会筛选出符合案例推荐规格/镜像的Notebook,您可以在Notebook列表选择目标Notebook,单击“打开 Notebook”

    • 新建Notebook

      如果您没有创建过Notebook,或者Notebook列表中没有符合本案例的Notebook,可以单击“新建 Notebook”“新建 Notebook”页面已预置了符合本案例的参数配置,您可以查看配置费用,单击“确定”。在“计费提醒”对话框,仔细阅读计费信息,单击“确定”。创建过程需2~5分钟,请您耐心等待。

      表1 新建Notebook参数说明

      参数

      说明

      名称

      Notebook的名称。系统会自动生成一个名称,您可以根据业务需求重新命名,命名规则:只能包含数字、大小写字母、下划线和中划线,长度不能超过128位且不能为空。

      选择镜像

      选择ModelArts官方镜像pytorch_2.7.1-cann_8.3.rc1-py_3.11-hce_2.0.2509-aarch64-snt9b。

      资源池类型

      公共资源池:无需单独购买,即开即用,按需付费,即按您的Notebook实例运行时长进行收费。

      实例规格

      NPU推荐使用单卡规格(Ascend: 1*ascend-snt9b1)或更高配置。

      磁盘容量

      建议20GB以上。

      自动停止

      开启后,可设置Notebook实例自动停止方式及对应时长,超出您预设的时长,它将自动停止运行(可能存在2-5分钟的延迟,此过程正常计费)。

  3. (可选)如果出现“Select Kernel”对话框,请选择PyTorch-2.7.1,单击“Select”

步骤二:下载Qwen3-8B模型

  1. 执行以下命令,安装ModelScope。
    !pip install modelscope

    在命令左侧,单击图标,执行命令。

  2. 执行以下命令,下载Qwen3-8B模型。
    !modelscope download --model 'Qwen/Qwen3-8B' --local_dir ./Qwen3-8B

    下载完成后,Qwen3-8B模型将出现在左侧目录下的“Qwen3-8B”文件夹中。

    图2 Qwen3-8B文件夹

步骤三:安装vLLM和vLLM-Ascend

请先执行步骤1,待步骤1执行成功后,再执行步骤2。如果操作顺序错误,可能导致版本不匹配,进而影响后续操作。

  1. 执行以下命令,安装vLLM。

    本案例的推理版本支持vllm=0.11.0,配合vllm-ascend的0.11.0版本适配A2硬件。

    !pip install vllm==0.11.0
  2. 执行以下命令,安装vLLM-Ascend。

    vllm-ascend的0.11.0适配vllm=0.11.0版本。

    !pip install vllm-ascend==0.11.0

步骤四:启动推理服务

  1. 设置推理服务端口、模型路径和模型名称。
    import os
    # 设置推理服务的端口,用户可自定义
    os.environ['port'] = '9001'
    port = os.environ['port']
    # 设置模型存储的路径
    os.environ['model_path'] = './Qwen3-8B'
    # 模型名称,用户可自定义
    os.environ['model_name'] = 'qwen3'
    model_name = os.environ['model_name']
  2. 执行以下命令,通过后台启动推理服务。
    %%bash
    
    source /usr/local/Ascend/ascend-toolkit/set_env.sh
    source /usr/local/Ascend/nnal/atb/set_env.sh
    
    export MODEL_PATH=$model_path
    export PORT=$port
    export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
    export OMP_PROC_BIND=false
    export OMP_NUM_THREADS=10
    export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
    export HCCL_BUFFSIZE=256
    export TASK_QUEUE_ENABLE=1
    export HCCL_OP_EXPANSION_MODE="AIV"
    export VLLM_USE_V1=1
    export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/mooncake:$LD_LIBRARY_PATH
    
    nohup vllm serve ${MODEL_PATH} \
      --port ${PORT} \
      --served-model-name ${model_name} \
      --max-model-len 5500 \
      --max-num-batched-tokens 40960 \
      --gpu-memory-utilization 0.90 \
      --enable-prefix-caching \
      --data-parallel-size 1 \
      --tensor-parallel-size 1 \
      --enforce-eager > vllm_qwen3.log 2>&1 &
  3. 执行以下命令,查看启动日志。

    执行启动推理服务命令后,多次运行以下命令查看启动日志,显示Application startup complete即为服务启动成功。

    %%bash
    # 查看vllm日志,查看启动结果/运行日志
    tail -n 100 vllm_qwen3.log
  4. 测试服务是否正常运行。

    推理服务启动完成后,运行以下脚本,测试推理服务是否正常运行,用户可修改content中问题内容。

    import subprocess
    import json
    
    data = {
        "messages": [{"role": "user", "content": "一周有几天"}],
        "stream": False,
        "max_tokens": 300
    }
    
    result = subprocess.run([
        "curl", "-X", "POST",
        f"http://127.0.0.1:{port}/v1/chat/completions",
        "-H", "Content-Type: application/json",
        "-d", json.dumps(data)
    ], capture_output=True, text=True)
    
    if result.returncode != 0:
        print("请求失败,错误信息:")
        print(result.stderr)
    else:
        try:
            response = json.loads(result.stdout)
            if "choices" in response and len(response["choices"]) > 0:
                message = response["choices"][0]["message"]["content"]
                print("模型回复:")
                print(message.strip())
            else:
                print("未找到有效回复内容。完整响应:")
                print(json.dumps(response, indent=2, ensure_ascii=False))
        except json.JSONDecodeError:
            print("无法解析 JSON 响应。原始输出:")
            print(result.stdout)

    输出示例:

    模型回复:
    <think>
    嗯,用户问“一周有几天”,这看起来是一个很基础的问题,但可能需要仔细考虑。首先,我需要确认用户的需求是什么。他们可能是在学习基础的时间单位,或者在做某个需要知道一周天数的任务,比如安排日程、计划活动等。也有可能用户对时间系统不太熟悉,或者想确认不同文化中的周天数是否一致。
    
    接下来,我得回想一下标准的周结构。通常来说,一周是7天,这在大多数国家都是通用的,比如星期一到星期日。不过,有时候可能会有不同的说法,比如有些地方可能把周日作为一周的开始,而有些地方则是周一开始。不过,国际标准通常是周日作为一周的结束,周一开始作为一周的开始,这可能因地区而异,但天数都是7天。
    
    然后,我需要考虑用户可能的背景。如果是孩子,可能需要更简单的解释,比如用例子说明每一天的名字,或者用日常活动来举例。如果是成年人,可能只需要直接回答7天,但也可以补充一些额外的信息,比如不同文化中的差异,或者一周在不同历法中的应用,比如公历和农历。
    
    另外,用户可能有更深层的需求。比如,他们可能在计划一周的活动,需要知道每天的安排;或者他们可能在学习语言,需要知道一周的英文名称;或者他们可能对时间管理感兴趣,想了解如何高效利用一周的时间

步骤五:使用Chatbot进行对话问答

  1. 安装Gradio组件,提供UI展示功能。
    !pip install gradio==5.50.0
  2. 设置Chatbot UI端口。
    server_port = 7890 # chat bot的端口,用户可自定义
  3. 启动Chatbot UI。

    执行以下脚本,输出"Running on local URL: http:127.0.0.1:server_port",表示启动成功。

    import json
    import os
    
    
    import gradio as gr
    import requests
    
    region_name = os.environ["REGION_NAME"]
    instance_id = os.environ["INSTANCE_ID"]
    base_path = f"/{instance_id}/proxy/{server_port}"
    console_url = f"https://authoring-modelarts.{region_name}.huaweicloud.com"
    server_name = "0.0.0.0"
    
    def chat_with_openai_stream(message, history):
        url = f"http://127.0.0.1:{port}/v1/chat/completions"
    
    
        messages = []
        for history_item in history:
            messages.append({"role": history_item["role"], "content": history_item["content"]})
        messages.append({"role": "user", "content": message})
    
        payload = {
            "model": model_name,
            "messages": messages,
            "max_tokens": 2048,
            "stream": True  # 开启流式响应
        }
    
        try:
            response = requests.post(url, json=payload, stream=True, timeout=120)
            response.raise_for_status()
    
            full_answer = ""    # 累计:提取后的【纯正式回复】内容
            full_think = ""     # 累计:提取后的【纯思考】内容
            has_think = False   # 标记:是否检测到思考内容,无则不展示思考模块
            think_over = False  # 是否思考完
            think_start = False # 是否开始思考完
    
    
            # 逐行处理流式响应
            for line in response.iter_lines():
                if line:
                    line_str = line.decode('utf-8')
    
                    if line_str.startswith('data: '):
                        line_str = line_str[6:]
    
                    if line_str.strip() == '[DONE]':
                        continue
    
                    try:
                        data = json.loads(line_str)
                        if 'choices' in data and len(data['choices']) > 0:
                            delta = data['choices'][0].get('delta', {})
                            current_content = delta.get('content', '')
    
                            if current_content:
                                if current_content == '<think>':
                                    has_think = True
                                    think_start = True
                                    continue
    
                                if think_start:
                                    current_content = current_content.replace('\n\n', '<br>').replace('\n', '<br>')
                                    full_think += current_content
    
                                if has_think and current_content == '</think>':
                                    think_over = True
                                    think_start = False
                                    continue
    
                                if think_over:
                                    full_answer += current_content
    
                                if not has_think:
                                    full_answer += current_content
    
                                if has_think and full_think:
                                    # 有思考内容:思考文本(灰色小字+思考中前缀) + 正式回复,分行展示,视觉区分明显
                                    show_text = f"<span style='color:#888; font-size:0.9em;'>【模型思考】{full_think}</span>\n\n{full_answer}"
    
                                if not has_think:
                                    # 无思考内容:只展示纯正式回复,和你原代码效果完全一致,无任何多余内容
                                    show_text = full_answer
    
                                # 流式返回,保留良好的打字机逐字效果
                                yield show_text
    
                    except json.JSONDecodeError:
                        continue
                    except Exception as e:
                        print(f"处理流数据时出错: {e}")
                        continue
    
        except Exception as e:
            error_msg = f"错误: {str(e)}"
            yield error_msg
    
    examples = [
        "你好,介绍一下你自己。",
        "32乘以12得多少。",
    ]
    
    # 创建 Gradio 界面
    demo = gr.ChatInterface(
        type="messages",
        fn=chat_with_openai_stream,
        title="Chat",
        description="与本地 qwen3 模型聊天",
        flagging_mode="manual",
        flagging_options=["Like", "Spam", "Inappropriate", "Other"],
        save_history=True,
        examples=examples
    )
    
    # 启动应用
    gradio_share = os.environ.get("GRADIO_SHARE", "0").lower() in ["true", "1"]
    demo.launch(
        share=gradio_share,
        inline=False,
        server_name=server_name,
        server_port=server_port,
        root_path=base_path
    )
  4. 展示Chatbot UI。

    运行以下脚本后,会展示Chatbot UI,您可以进行聊天对话。

    proxy_url = f"{console_url}{base_path}/"
    from IPython.display import IFrame, display
    display(IFrame(src=proxy_url, width="100%", height="800"))
    图3 与机器人进行对话

更多案例

ModelArts新版控制台提供了很多Notebook的入门案例,您可以登录ModelArts新版控制台,在左侧导航栏选择“快速入门”,在“开发实践”页签单击案例卡片,了解案例详细说明,也可以在案例卡片中单击“开发”,快速实现对应的功能。部分开发实践案例名称如下:

  • 使用profiling工具采集Qwen3模型训练性能数据及tensorboard可视化
  • 基于Ascend和ComfyUI实现AI视频生成
  • 使用llama-factory进行交互式lora微调实现中国历史人物角色扮演
图4 开发实践

相关文档