通义千问2.5-7B-Instruct自动化测试案例:CI/CD集成部署教程

1. 引言

随着大语言模型在企业级应用中的广泛落地,如何高效、稳定地将模型服务集成到持续集成与持续交付(CI/CD)流程中,成为工程团队关注的核心问题。通义千问2.5-7B-Instruct作为阿里于2024年9月发布的高性能开源指令微调模型,具备高推理效率、强代码理解能力及良好的量化支持,非常适合部署在自动化测试和DevOps场景中。

本文将以 vLLM + Open WebUI 的组合方式,完整演示如何将 Qwen2.5-7B-Instruct 模型部署为本地API服务,并通过Jenkins流水线实现CI/CD自动化测试集成。文章涵盖环境准备、模型部署、接口调用、自动化脚本编写以及常见问题优化,适合AI工程师、DevOps人员和测试开发团队参考实践。

2. 技术选型与架构设计

2.1 核心组件说明

本方案采用以下技术栈:

  • vLLM:高性能大模型推理框架,支持PagedAttention、连续批处理(Continuous Batching),显著提升吞吐量。
  • Open WebUI:轻量级前端界面,提供类ChatGPT的交互体验,同时暴露REST API供程序调用。
  • Docker Compose:用于统一管理多个容器化服务,简化部署流程。
  • Jenkins:CI/CD核心调度工具,执行自动化测试任务并调用模型API。
  • Python Requests:用于构建自动化测试脚本,向模型发送请求并验证响应。

2.2 系统架构图

+------------------+     +---------------------+
|   Jenkins Job    | --> | REST API (OpenWebUI)|
+------------------+     +----------+----------+
                                    |
                                    v
                          +---------+---------+
                          |   vLLM Inference  |
                          | Qwen2.5-7B-Instruct|
                          +-------------------+

整个系统通过Docker容器运行模型服务,Jenkins定时触发测试任务,调用模型生成结果,并进行断言校验,形成闭环自动化流程。

3. 环境准备与模型部署

3.1 前置条件

确保主机满足以下要求:

  • GPU显存 ≥ 12GB(推荐RTX 3060及以上)
  • CUDA驱动已安装(版本 ≥ 12.1)
  • Docker 和 Docker Compose 已配置
  • Python 3.10+ 环境可用
  • Git 工具已安装

3.2 部署步骤

步骤1:克隆项目仓库
git clone https://github.com/kaka-j/qwen-vllm-openwebui.git
cd qwen-vllm-openwebui
步骤2:启动服务(使用Docker Compose)
# docker-compose.yml
version: '3.8'
services:
  vllm:
    image: vllm/vllm-openai:latest
    container_name: vllm_qwen
    runtime: nvidia
    environment:
      - NVIDIA_VISIBLE_DEVICES=all
    command:
      - "--model"
      - "Qwen/Qwen2.5-7B-Instruct"
      - "--dtype"
      - "half"
      - "--max-model-len"
      - "131072"
      - "--enable-auto-tool-call"
      - "--tool-call-parser"
      - "qwen"
    ports:
      - "8000:8000"
    restart: unless-stopped

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    volumes:
      - ./models:/app/models
    ports:
      - "7860:7860"
    environment:
      - OLLAMA_BASE_URL=http://vllm:8000/v1
    depends_on:
      - vllm
    restart: unless-stopped

运行命令启动服务:

docker compose up -d

⚠️ 首次启动需下载模型文件,耗时约5–10分钟,请耐心等待。

步骤3:访问Web界面

打开浏览器访问:http://localhost:7860

登录账号信息如下:

账号:kakajiang@kakajiang.com
密码:kakajiang

此时可手动测试模型问答、代码生成等功能。

4. API接口调用与功能验证

4.1 获取认证Token

首次使用需获取Bearer Token:

curl -X POST "http://localhost:7860/api/v1/auths/token" \
     -H "Content-Type: application/json" \
     -d '{
           "email": "kakajiang@kakajiang.com",
           "password": "kakajiang"
         }'

返回示例:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx",
  "token_type": "bearer"
}

4.2 发送推理请求(代码生成示例)

import requests

url = "http://localhost:7860/api/v1/chat/completions"
headers = {
    "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx",
    "Content-Type": "application/json"
}

data = {
    "model": "Qwen2.5-7B-Instruct",
    "messages": [
        {"role": "user", "content": "写一个Python函数,判断一个数是否为质数"}
    ],
    "temperature": 0.5,
    "max_tokens": 200
}

response = requests.post(url, json=data, headers=headers)
print(response.json()['choices'][0]['message']['content'])

输出示例:

def is_prime(n):
    if n <= 1:
        return False
    if n == 2:
        return True
    if n % 2 == 0:
        return False
    for i in range(3, int(n**0.5)+1, 2):
        if n % i == 0:
            return False
    return True

5. 自动化测试脚本开发

5.1 测试目标定义

我们设定以下自动化测试用例:

用例编号 输入内容 预期输出关键词 断言类型
TC001 “斐波那契数列前10项” 0, 1, 1, 2, 3, 5... 包含匹配
TC002 “Linux下查看磁盘使用率的命令” df -h 完全匹配
TC003 “JSON格式返回今天的日期” "date": "\d{4}-\d{2} 正则匹配

5.2 编写Python测试脚本

# test_qwen_automation.py
import requests
import re
import time
import logging

logging.basicConfig(level=logging.INFO)
TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx"
BASE_URL = "http://localhost:7860/api/v1/chat/completions"
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}

TEST_CASES = [
    {
        "name": "TC001",
        "prompt": "生成斐波那契数列的前10项",
        "expected": "0, 1, 1, 2, 3, 5, 8, 13, 21, 34",
        "check_type": "contains"
    },
    {
        "name": "TC002",
        "prompt": "Linux下查看磁盘使用率的命令是什么?",
        "expected": "df -h",
        "check_type": "exact"
    },
    {
        "name": "TC003",
        "prompt": "以JSON格式返回今天的日期",
        "expected": r'"date":\s*"\d{4}-\d{2}-\d{2}"',
        "check_type": "regex"
    }
]

def call_model(prompt):
    data = {
        "model": "Qwen2.5-7B-Instruct",
        "messages": [{"role": "user", "content": prompt}],
        "max_tokens": 150,
        "temperature": 0.3
    }
    try:
        resp = requests.post(BASE_URL, json=data, headers=HEADERS, timeout=60)
        resp.raise_for_status()
        return resp.json()['choices'][0]['message']['content']
    except Exception as e:
        logging.error(f"API调用失败: {e}")
        return ""

def run_tests():
    passed = 0
    total = len(TEST_CASES)

    for case in TEST_CASES:
        print(f"\nRunning {case['name']}: {case['prompt']}")
        time.sleep(2)  # 避免请求过快
        output = call_model(case['prompt'])

        if case['check_type'] == 'exact' and case['expected'].lower() in output.lower():
            result = 'PASS'
            passed += 1
        elif case['check_type'] == 'contains' and case['expected'] in output:
            result = 'PASS'
            passed += 1
        elif case['check_type'] == 'regex' and re.search(case['expected'], output):
            result = 'PASS'
            passed += 1
        else:
            result = 'FAIL'

        print(f"[{result}] Output: {output}")

    print(f"\n✅ 测试完成:{passed}/{total} 通过")
    return passed == total

if __name__ == "__main__":
    success = run_tests()
    exit(0 if success else 1)

6. CI/CD集成:Jenkins自动化流水线

6.1 Jenkinsfile定义

// Jenkinsfile
pipeline {
    agent any

    environment {
        PYTHON_ENV = "/opt/venv/bin"
    }

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/kaka-j/qwen-vllm-openwebui.git'
            }
        }

        stage('Start Services') {
            steps {
                sh 'docker compose down || true'
                sh 'docker compose up -d'
                script {
                    // 等待模型加载完成
                    def ready = false
                    for (int i = 0; i < 15; i++) {
                        def status = sh(script: "curl -s http://localhost:8000/health", returnStatus: true)
                        if (status == 0) {
                            ready = true
                            break
                        }
                        sleep(20)
                    }
                    if (!ready) {
                        error("vLLM服务未能正常启动")
                    }
                }
            }
        }

        stage('Run Tests') {
            steps {
                sh '''
                    python3 -m venv /opt/venv
                    source /opt/venv/bin/activate
                    pip install requests pytest
                    python test_qwen_automation.py
                '''
            }
        }

        stage('Notify Result') {
            steps {
                script {
                    if (currentBuild.result == 'SUCCESS') {
                        echo '✅ 自动化测试全部通过!'
                    } else {
                        echo '❌ 存在测试失败,请检查模型响应质量。'
                    }
                }
            }
        }
    }

    post {
        always {
            sh 'docker compose down'
        }
    }
}

6.2 流水线执行逻辑说明

  1. 拉取代码:从Git仓库获取最新部署配置和测试脚本。
  2. 启动服务:使用Docker Compose启动vLLM和Open WebUI服务。
  3. 健康检查:轮询 /health 接口确认模型已就绪。
  4. 执行测试:运行Python脚本发起多轮推理请求并验证输出。
  5. 清理资源:无论成功与否,最终关闭所有容器。

7. 性能优化与常见问题

7.1 提升推理速度建议

  • 使用 KV Cache量化(如--quantization awq)降低显存占用;
  • 启用 Tensor Parallelism 多卡并行(若有多GPU);
  • 调整 --max-num-seqs 参数控制并发请求数;
  • 使用 GGUF量化模型 在低配设备运行(仅CPU模式)。

7.2 常见错误排查

问题现象 可能原因 解决方案
模型无法加载 显存不足或CUDA版本不兼容 升级驱动或改用fp16/awq量化版本
Open WebUI连接vLLM失败 网络未打通或URL错误 检查OLLAMA_BASE_URL指向正确端口
返回空响应 token过期或权限不足 重新获取JWT token
Jenkins超时 模型加载时间过长 增加wait循环次数或启用缓存镜像

8. 总结

8.1 实践价值总结

本文详细介绍了如何将 通义千问2.5-7B-Instruct 模型通过 vLLM + Open WebUI 方式部署,并成功集成至 Jenkins CI/CD流水线 中,实现了自动化测试闭环。该方案具备以下优势:

  • 商用合规:Qwen系列模型允许商业用途,适合企业内部系统集成;
  • 高性能推理:vLLM加持下,单卡可达 >100 tokens/s,满足实时性需求;
  • 易扩展性强:可通过Docker快速复制部署至测试、预发、生产环境;
  • 自动化友好:REST API标准化,便于与各类测试框架对接。

8.2 最佳实践建议

  1. 建立模型健康检查机制:每次CI运行前验证模型服务可用性;
  2. 设置响应质量评分规则:结合BLEU、ROUGE等指标评估输出一致性;
  3. 日志留存与分析:记录每次推理输入输出,用于后续审计与调试;
  4. 定期更新模型版本:跟踪Qwen官方更新,及时升级至更优版本。

获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

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

更多推荐