千问3.5-27B部署教程:Ansible自动化脚本实现百台GPU服务器批量部署
本文介绍了如何利用星图GPU平台,通过Ansible自动化脚本高效、批量地部署千问3.5-27B镜像。该方案能显著简化在百台GPU服务器集群上的部署流程,确保环境一致性。部署后的千问3.5-27B模型可快速投入实际应用,例如为智能客服、内容创作等场景提供强大的多模态对话与文本生成能力。
千问3.5-27B部署教程:Ansible自动化脚本实现百台GPU服务器批量部署
1. 引言:从单机到集群的部署挑战
想象一下,你刚刚在单台服务器上成功部署了千问3.5-27B模型,体验到了它强大的多模态对话能力。现在,老板给你下达了一个新任务:需要在两周内,将这套系统部署到公司新采购的100台GPU服务器上,为即将上线的新产品提供AI服务支持。
你可能会想:“一台一台手动部署?那得干到猴年马月。” 配置环境、安装依赖、下载模型、启动服务……每个步骤都可能遇到不同的问题,重复劳动不仅效率低下,还容易出错。这就是我们今天要解决的核心问题:如何将复杂的AI模型部署,从繁琐的手工操作,转变为高效、可靠的自动化流程。
本文将带你一步步构建一个基于Ansible的自动化部署方案,让你能够像管理一台服务器一样,轻松管理上百台GPU服务器集群。无论你是运维工程师、AI算法工程师,还是技术负责人,这套方案都能帮你大幅提升部署效率,确保环境一致性。
2. 环境准备与Ansible基础
2.1 为什么选择Ansible?
在开始之前,我们先简单了解一下为什么选择Ansible作为我们的自动化工具。Ansible有以下几个核心优势:
- 无代理架构:不需要在目标服务器上安装任何客户端,通过SSH就能完成所有操作
- 声明式语法:用YAML编写剧本(Playbook),描述“最终状态”而非具体步骤,更直观
- 幂等性:无论执行多少次,结果都是一致的,避免重复操作带来的问题
- 模块化设计:丰富的内置模块,覆盖文件管理、包安装、服务控制等常见需求
对于我们的千问3.5-27B部署场景,这些特性正好解决了批量部署中的关键痛点:环境一致性、操作可重复性、错误可追溯性。
2.2 控制节点环境搭建
首先,我们需要准备一台“控制节点”服务器,它将负责向所有目标GPU服务器发送指令。这台机器可以是你的本地开发机,也可以是一台专门的运维服务器。
# 在控制节点上安装Ansible
# 对于Ubuntu/Debian系统
sudo apt update
sudo apt install -y ansible sshpass
# 对于CentOS/RHEL系统
sudo yum install -y epel-release
sudo yum install -y ansible sshpass
# 验证安装
ansible --version
安装完成后,我们需要配置Ansible的主机清单(Inventory)。主机清单定义了我们要管理的所有服务器。
# 创建项目目录结构
mkdir -p ~/qwen-deploy/{inventory,playbooks,roles,files}
cd ~/qwen-deploy
# 创建主机清单文件
cat > inventory/hosts.ini << 'EOF'
[gpu_servers]
gpu-server-01 ansible_host=192.168.1.101 ansible_user=root
gpu-server-02 ansible_host=192.168.1.102 ansible_user=root
gpu-server-03 ansible_host=192.168.1.103 ansible_user=root
# ... 可以继续添加更多服务器
[gpu_servers:vars]
# 所有GPU服务器的通用变量
ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible_python_interpreter=/usr/bin/python3
model_name=Qwen3.5-27B
model_path=/root/ai-models/Qwen/Qwen3.5-27B
service_port=7860
EOF
在实际环境中,你可能会有几十甚至上百台服务器。Ansible支持动态清单,可以从云平台API、CMDB系统或简单的文本文件中读取主机信息。这里我们使用静态文件作为示例。
2.3 SSH免密登录配置
为了让Ansible能够自动登录到所有目标服务器,我们需要配置SSH免密登录。这是自动化部署的前提条件。
# 1. 在控制节点生成SSH密钥(如果还没有)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""
# 2. 将公钥分发到所有目标服务器
# 首先测试单台服务器的连接
ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.101
# 3. 使用Ansible批量分发公钥(需要先配置好部分服务器的密码)
cat > playbooks/setup-ssh.yml << 'EOF'
---
- name: 设置SSH免密登录
hosts: gpu_servers
gather_facts: no
vars:
ansible_ssh_user: root
ansible_ssh_pass: "{{ ssh_password }}" # 首次运行时需要密码
tasks:
- name: 创建.ssh目录
file:
path: /root/.ssh
state: directory
mode: '0700'
- name: 添加控制节点公钥
authorized_key:
user: root
state: present
key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
EOF
# 运行剧本(首次需要密码)
ansible-playbook -i inventory/hosts.ini playbooks/setup-ssh.yml --extra-vars "ssh_password=your_initial_password"
完成SSH配置后,我们可以测试一下连接是否正常:
# 测试所有服务器的连通性
ansible -i inventory/hosts.ini gpu_servers -m ping
# 如果一切正常,你会看到类似这样的输出:
# gpu-server-01 | SUCCESS => {
# "changed": false,
# "ping": "pong"
# }
# gpu-server-02 | SUCCESS => {
# "changed": false,
# "ping": "pong"
# }
3. 千问3.5-27B自动化部署剧本
现在我们已经准备好了基础环境,接下来开始编写部署千问3.5-27B的核心剧本。我们将把整个部署过程分解为多个独立的角色(Role),每个角色负责一个特定的功能模块。
3.1 创建角色目录结构
Ansible的角色(Role)是一种组织Playbook的方式,它把相关的任务、变量、文件等组织在一起,便于复用和维护。
# 创建基础系统配置角色
mkdir -p roles/base/tasks
mkdir -p roles/base/files
mkdir -p roles/base/templates
# 创建Docker环境角色
mkdir -p roles/docker/tasks
# 创建模型部署角色
mkdir -p roles/qwen-deploy/tasks
mkdir -p roles/qwen-deploy/files
mkdir -p roles/qwen-deploy/templates
# 创建服务管理角色
mkdir -p roles/service/tasks
mkdir -p roles/service/templates
3.2 基础系统配置角色
这个角色负责在所有GPU服务器上配置基础环境,包括系统更新、必要的工具安装、NVIDIA驱动检查等。
# roles/base/tasks/main.yml
---
- name: 更新系统包缓存
apt:
update_cache: yes
cache_valid_time: 3600
when: ansible_os_family == "Debian"
- name: 安装基础工具
apt:
name:
- curl
- wget
- git
- vim
- htop
- net-tools
- python3-pip
- python3-venv
state: present
when: ansible_os_family == "Debian"
- name: 检查NVIDIA驱动
shell: nvidia-smi --query-gpu=name,memory.total --format=csv,noheader
register: nvidia_info
ignore_errors: yes
changed_when: false
- name: 显示GPU信息
debug:
msg: "GPU信息: {{ nvidia_info.stdout }}"
- name: 创建模型存储目录
file:
path: "{{ model_path }}"
state: directory
mode: '0755'
- name: 创建服务目录
file:
path: /opt/qwen3527-27b
state: directory
mode: '0755'
3.3 Docker环境配置角色
千问3.5-27B的部署通常需要特定的Python环境和依赖。使用Docker可以确保环境的一致性,避免“在我机器上能运行”的问题。
# roles/docker/tasks/main.yml
---
- name: 安装Docker依赖
apt:
name:
- apt-transport-https
- ca-certificates
- curl
- gnupg
- lsb-release
state: present
when: ansible_os_family == "Debian"
- name: 添加Docker官方GPG密钥
apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
when: ansible_os_family == "Debian"
- name: 添加Docker仓库
apt_repository:
repo: "deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
state: present
when: ansible_os_family == "Debian"
- name: 安装Docker引擎
apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
state: present
when: ansible_os_family == "Debian"
- name: 启动Docker服务
systemd:
name: docker
state: started
enabled: yes
- name: 安装NVIDIA Docker运行时
shell: |
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
&& curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
&& curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
when: ansible_os_family == "Debian"
- name: 安装nvidia-docker2
apt:
name: nvidia-docker2
state: present
update_cache: yes
when: ansible_os_family == "Debian"
- name: 重启Docker服务
systemd:
name: docker
state: restarted
- name: 测试NVIDIA Docker
shell: docker run --rm --gpus all nvidia/cuda:11.8.0-base-ubuntu22.04 nvidia-smi
register: nvidia_docker_test
changed_when: false
- name: 显示NVIDIA Docker测试结果
debug:
msg: "NVIDIA Docker测试: {{ nvidia_docker_test.stdout_lines[0:2] | join('\n') }}"
3.4 千问3.5-27B部署角色
这是最核心的角色,负责拉取模型、配置环境、启动服务。我们将使用Docker Compose来管理整个服务栈。
首先,创建Docker Compose配置文件模板:
# roles/qwen-deploy/templates/docker-compose.yml.j2
version: '3.8'
services:
qwen3527:
image: {{ docker_image | default("qwen3527:latest") }}
container_name: qwen3527
restart: unless-stopped
ports:
- "{{ service_port }}:7860"
volumes:
- "{{ model_path }}:/app/models"
- "./logs:/app/logs"
- "./config:/app/config"
environment:
- MODEL_PATH=/app/models/Qwen3.5-27B
- MAX_NEW_TOKENS=256
- DEVICE=cuda
- NUM_GPUS=4
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: all
capabilities: [gpu]
command: >
python -m uvicorn main:app
--host 0.0.0.0
--port 7860
--workers 1
networks:
- qwen-network
networks:
qwen-network:
driver: bridge
接下来,创建部署任务:
# roles/qwen-deploy/tasks/main.yml
---
- name: 下载模型文件(如果不存在)
block:
- name: 检查模型是否已存在
stat:
path: "{{ model_path }}/config.json"
register: model_exists
- name: 从镜像服务器下载模型
shell: |
set -e
cd {{ model_path }}
if [ ! -f "config.json" ]; then
echo "开始下载模型文件..."
# 这里可以使用wget、rsync或scp从中央存储下载
# 示例:wget -q http://model-server/qwen3.5-27b.tar.gz
# tar -xzf qwen3.5-27b.tar.gz
# 实际生产环境建议使用专用的模型分发系统
echo "模型下载完成"
else
echo "模型已存在,跳过下载"
fi
args:
executable: /bin/bash
when: not model_exists.stat.exists
register: download_result
- name: 显示下载结果
debug:
msg: "模型准备状态: {{ download_result.stdout }}"
rescue:
- name: 下载失败处理
debug:
msg: "模型下载失败,请检查网络连接或存储服务器状态"
- name: 创建Docker镜像构建文件
template:
src: Dockerfile.j2
dest: /opt/qwen3527-27b/Dockerfile
mode: '0644'
- name: 创建Docker Compose配置
template:
src: docker-compose.yml.j2
dest: /opt/qwen3527-27b/docker-compose.yml
mode: '0644'
- name: 创建服务配置文件
copy:
src: supervisor.conf
dest: /etc/supervisor/conf.d/qwen3527.conf
mode: '0644'
notify: 重载Supervisor配置
- name: 构建Docker镜像
shell: |
cd /opt/qwen3527-27b
docker build -t qwen3527:latest .
args:
chdir: /opt/qwen3527-27b
register: build_result
- name: 启动服务
shell: |
cd /opt/qwen3527-27b
docker-compose up -d
args:
chdir: /opt/qwen3527-27b
register: startup_result
- name: 检查服务状态
shell: |
sleep 10 # 等待服务启动
curl -s http://localhost:{{ service_port }}/health || echo "服务未就绪"
register: health_check
changed_when: false
- name: 显示服务状态
debug:
msg: |
服务启动结果: {{ startup_result.stdout }}
健康检查: {{ health_check.stdout }}
3.5 服务管理角色
这个角色负责服务的监控、日志管理和日常维护。
# roles/service/tasks/main.yml
---
- name: 安装Supervisor
apt:
name: supervisor
state: present
when: ansible_os_family == "Debian"
- name: 配置Supervisor服务管理
template:
src: qwen3527_supervisor.conf.j2
dest: /etc/supervisor/conf.d/qwen3527.conf
mode: '0644'
notify: 重载Supervisor配置
- name: 创建日志轮转配置
copy:
src: qwen3527_logrotate
dest: /etc/logrotate.d/qwen3527
mode: '0644'
- name: 设置监控脚本
copy:
src: check_qwen_service.sh
dest: /usr/local/bin/check_qwen_service.sh
mode: '0755'
- name: 添加定时监控任务
cron:
name: "监控千问服务"
minute: "*/5"
job: "/usr/local/bin/check_qwen_service.sh"
user: root
- name: 配置防火墙规则
ufw:
rule: allow
port: "{{ service_port }}"
proto: tcp
when: ansible_os_family == "Debian"
- name: 显示服务访问信息
debug:
msg: |
服务部署完成!
访问地址: http://{{ ansible_host }}:{{ service_port }}
API端点: http://{{ ansible_host }}:{{ service_port }}/generate
图片理解API: http://{{ ansible_host }}:{{ service_port }}/generate_with_image
4. 整合部署剧本与批量执行
现在我们已经创建了所有必要的角色,接下来需要创建一个主剧本(Playbook)来协调这些角色的执行顺序。
4.1 主部署剧本
# playbooks/deploy_qwen_cluster.yml
---
- name: 部署千问3.5-27B集群 - 基础环境准备
hosts: gpu_servers
serial: 10 # 每次在10台服务器上并行执行
gather_facts: yes
roles:
- role: base
tags: base
- name: 部署千问3.5-27B集群 - Docker环境
hosts: gpu_servers
serial: 10
roles:
- role: docker
tags: docker
- name: 部署千问3.5-27B集群 - 模型服务
hosts: gpu_servers
serial: 5 # 模型部署比较耗时,减少并行数
roles:
- role: qwen-deploy
tags: qwen-deploy
- name: 部署千问3.5-27B集群 - 服务管理
hosts: gpu_servers
serial: 20 # 服务管理可以并行更多
roles:
- role: service
tags: service
- name: 验证集群部署
hosts: gpu_servers
gather_facts: no
tasks:
- name: 检查服务端口
wait_for:
port: "{{ service_port }}"
host: "{{ ansible_host }}"
timeout: 30
delegate_to: localhost
- name: 测试API接口
uri:
url: "http://{{ ansible_host }}:{{ service_port }}/health"
method: GET
status_code: 200
timeout: 10
register: api_test
delegate_to: localhost
- name: 记录验证结果
debug:
msg: "服务器 {{ ansible_host }} 部署{{ '成功' if api_test.status == 200 else '失败' }}"
4.2 执行批量部署
有了完整的剧本,现在可以开始批量部署了。Ansible提供了多种执行策略,我们可以根据实际情况选择。
# 1. 完整部署(所有服务器)
ansible-playbook -i inventory/hosts.ini playbooks/deploy_qwen_cluster.yml
# 2. 分阶段部署(先部署基础环境)
ansible-playbook -i inventory/hosts.ini playbooks/deploy_qwen_cluster.yml --tags base,docker
# 3. 只部署模型服务(当基础环境已就绪时)
ansible-playbook -i inventory/hosts.ini playbooks/deploy_qwen_cluster.yml --tags qwen-deploy,service
# 4. 只部署特定服务器组
ansible-playbook -i inventory/hosts.ini playbooks/deploy_qwen_cluster.yml --limit "gpu-server-01,gpu-server-02"
# 5. 检查模式(模拟执行,不实际修改)
ansible-playbook -i inventory/hosts.ini playbooks/deploy_qwen_cluster.yml --check
# 6. 详细输出模式(调试用)
ansible-playbook -i inventory/hosts.ini playbooks/deploy_qwen_cluster.yml -vvv
4.3 处理部署中的常见问题
在批量部署过程中,可能会遇到各种问题。Ansible提供了强大的错误处理和重试机制。
# playbooks/handle_failures.yml
---
- name: 带错误处理的部署
hosts: gpu_servers
strategy: linear
max_fail_percentage: 20 # 允许20%的服务器失败
any_errors_fatal: false # 单个服务器失败不影响其他服务器
tasks:
- name: 尝试部署服务
block:
- name: 执行部署
include_role:
name: qwen-deploy
- name: 验证部署
uri:
url: "http://localhost:{{ service_port }}/health"
method: GET
status_code: 200
register: health_check
until: health_check.status == 200
retries: 5
delay: 10
rescue:
- name: 记录失败服务器
debug:
msg: "服务器 {{ ansible_host }} 部署失败,已跳过"
- name: 将失败服务器加入重试列表
add_host:
name: "{{ ansible_host }}"
groups: failed_servers
- name: 清理临时文件
file:
path: "/tmp/qwen_deploy_*.tmp"
state: absent
- name: 停止可能残留的服务
shell: |
cd /opt/qwen3527-27b 2>/dev/null && docker-compose down || true
ignore_errors: yes
- name: 重试失败的服务器
hosts: failed_servers
tasks:
- name: 重新部署失败服务器
include_role:
name: qwen-deploy
5. 集群管理与维护
部署完成后,我们还需要一套机制来管理整个集群。Ansible同样可以帮我们实现集群级别的管理任务。
5.1 集群状态监控
# playbooks/cluster_monitor.yml
---
- name: 收集集群状态信息
hosts: gpu_servers
gather_facts: no
tasks:
- name: 检查服务运行状态
shell: |
docker ps --filter "name=qwen3527" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
register: service_status
- name: 检查GPU使用情况
shell: nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total --format=csv,noheader
register: gpu_usage
- name: 检查API可用性
uri:
url: "http://localhost:{{ service_port }}/health"
method: GET
timeout: 5
register: api_health
ignore_errors: yes
- name: 汇总服务器状态
set_fact:
server_status: |
主机: {{ ansible_host }}
服务状态: {{ service_status.stdout_lines[1] if service_status.stdout_lines|length > 1 else '未运行' }}
GPU使用: {{ gpu_usage.stdout }}
API健康: {{ '正常' if api_health.status == 200 else '异常' }}
- name: 输出状态信息
debug:
msg: "{{ server_status }}"
- name: 生成集群状态报告
hosts: localhost
gather_facts: no
tasks:
- name: 汇总所有服务器状态
debug:
msg: "集群监控完成,详细状态见各服务器输出"
5.2 批量服务操作
# playbooks/cluster_operations.yml
---
- name: 重启集群所有服务
hosts: gpu_servers
tasks:
- name: 重启Docker服务
shell: |
cd /opt/qwen3527-27b
docker-compose restart
args:
chdir: /opt/qwen3527-27b
- name: 等待服务恢复
wait_for:
port: "{{ service_port }}"
delay: 5
timeout: 60
- name: 更新集群模型
hosts: gpu_servers
serial: 3 # 分批更新,避免同时下载造成网络拥堵
tasks:
- name: 停止服务
shell: |
cd /opt/qwen3527-27b
docker-compose down
args:
chdir: /opt/qwen3527-27b
- name: 备份旧模型
shell: |
cp -r {{ model_path }} {{ model_path }}_backup_$(date +%Y%m%d_%H%M%S)
- name: 下载新模型
# 这里替换为实际的模型更新逻辑
shell: |
echo "开始更新模型..."
# 实际生产环境应该从模型仓库拉取
sleep 10 # 模拟下载过程
- name: 重启服务
shell: |
cd /opt/qwen3527-27b
docker-compose up -d
args:
chdir: /opt/qwen3527-27b
- name: 清理集群日志
hosts: gpu_servers
tasks:
- name: 清理旧日志
shell: |
find /opt/qwen3527-27b/logs -name "*.log" -mtime +7 -delete
docker system prune -f --filter "until=24h"
5.3 性能监控与优化
# playbooks/performance_monitor.yml
---
- name: 收集性能指标
hosts: gpu_servers
tasks:
- name: 收集系统负载
shell: uptime
register: system_load
- name: 收集内存使用
shell: free -h
register: memory_usage
- name: 收集磁盘空间
shell: df -h / /opt
register: disk_space
- name: 收集GPU详细状态
shell: nvidia-smi
register: gpu_detail
- name: 测试API响应时间
shell: |
time curl -s -o /dev/null -w "%{time_total}" http://localhost:7860/health
register: api_response_time
- name: 生成性能报告
debug:
msg: |
性能报告 - {{ ansible_host }}
系统负载: {{ system_load.stdout }}
内存使用: {{ memory_usage.stdout_lines[1] }}
磁盘空间: {{ disk_space.stdout }}
API响应时间: {{ api_response_time.stdout }}秒
GPU状态:
{{ gpu_detail.stdout }}
- name: 优化建议
hosts: gpu_servers
tasks:
- name: 检查是否需要优化
shell: |
# 检查GPU内存使用率
nvidia-smi --query-gpu=memory.used,memory.total --format=csv,noheader | awk -F', ' '{used=$1; total=$2; gsub(/[^0-9]/,"",used); gsub(/[^0-9]/,"",total); if (used/total > 0.9) print "GPU内存使用过高"}'
register: gpu_check
- name: 提供优化建议
debug:
msg: |
{{ ansible_host }} 优化建议:
{{ gpu_check.stdout if gpu_check.stdout != "" else "当前运行状态良好" }}
建议操作:
1. 调整max_new_tokens参数减少内存使用
2. 考虑使用vLLM优化推理速度
3. 检查日志是否有异常错误
6. 实战案例:百台服务器部署演练
让我们通过一个完整的实战案例,看看如何在实际环境中使用这套自动化方案。
6.1 准备阶段
假设我们有一个包含100台GPU服务器的集群,IP地址范围是192.168.1.101到192.168.1.200。
# 生成主机清单
cat > inventory/production_hosts.ini << 'EOF'
[gpu_cluster]
gpu-[101:200] ansible_host=192.168.1.[101:200] ansible_user=root
[gpu_cluster:vars]
ansible_ssh_private_key_file=~/.ssh/production_key
model_path=/data/models/Qwen3.5-27B
service_port=7860
batch_size=10
EOF
# 测试连接
ansible -i inventory/production_hosts.ini gpu_cluster -m ping --forks 20
6.2 分批次部署
由于100台服务器同时部署可能会对网络和存储造成压力,我们采用分批次策略:
# 第一阶段:基础环境部署(20台并行)
ansible-playbook -i inventory/production_hosts.ini playbooks/deploy_qwen_cluster.yml \
--limit "gpu-[101:120]" \
--tags base,docker \
--forks 20
# 第二阶段:模型部署(10台并行,避免同时下载大文件)
ansible-playbook -i inventory/production_hosts.ini playbooks/deploy_qwen_cluster.yml \
--limit "gpu-[101:120]" \
--tags qwen-deploy \
--forks 10
# 第三阶段:服务部署(20台并行)
ansible-playbook -i inventory/production_hosts.ini playbooks/deploy_qwen_cluster.yml \
--limit "gpu-[101:120]" \
--tags service \
--forks 20
# 验证第一批服务器
ansible -i inventory/production_hosts.ini gpu-[101:120] -m shell -a "curl -s http://localhost:7860/health"
# 如果第一批成功,继续部署剩余服务器
for start in {121..200..20}; do
end=$((start+19))
echo "部署服务器 gpu-[$start:$end]"
ansible-playbook -i inventory/production_hosts.ini playbooks/deploy_qwen_cluster.yml \
--limit "gpu-[$start:$end]" \
--forks 20
done
6.3 部署结果验证
部署完成后,我们需要验证整个集群的状态:
# 创建验证脚本
cat > scripts/verify_cluster.sh << 'EOF'
#!/bin/bash
# 验证所有服务器的服务状态
echo "开始验证集群状态..."
echo "======================"
total_servers=100
success_count=0
failed_servers=()
for i in {101..200}; do
ip="192.168.1.$i"
echo -n "检查服务器 $ip ... "
# 尝试连接并检查服务
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@$ip \
"curl -s -m 10 http://localhost:7860/health" 2>/dev/null | grep -q "OK"; then
echo "✓ 正常"
((success_count++))
else
echo "✗ 失败"
failed_servers+=("$ip")
fi
done
echo "======================"
echo "部署完成报告:"
echo "总服务器数: $total_servers"
echo "成功部署: $success_count"
echo "失败部署: $(($total_servers - $success_count))"
if [ ${#failed_servers[@]} -gt 0 ]; then
echo "失败的服务器:"
printf '%s\n' "${failed_servers[@]}"
# 生成重试清单
echo "生成重试清单..."
echo "[retry_servers]" > inventory/retry_hosts.ini
for ip in "${failed_servers[@]}"; do
echo "$ip ansible_host=$ip ansible_user=root" >> inventory/retry_hosts.ini
done
fi
EOF
chmod +x scripts/verify_cluster.sh
./scripts/verify_cluster.sh
6.4 性能基准测试
部署完成后,我们可以运行一个简单的性能测试,了解集群的整体表现:
# playbooks/benchmark_test.yml
---
- name: 集群性能基准测试
hosts: gpu_cluster
serial: 5 # 控制并发数,避免压垮测试工具
tasks:
- name: 准备测试数据
copy:
content: |
{"prompt": "请用中文介绍一下你自己。", "max_new_tokens": 128}
dest: /tmp/test_prompt.json
mode: '0644'
- name: 运行API性能测试
shell: |
# 测试10次请求的平均响应时间
total_time=0
for i in {1..10}; do
start_time=$(date +%s%N)
curl -X POST http://localhost:7860/generate \
-H "Content-Type: application/json" \
--data @/tmp/test_prompt.json \
-o /dev/null -s -w "%{time_total}\n"
end_time=$(date +%s%N)
request_time=$(echo "scale=3; ($end_time - $start_time) / 1000000000" | bc)
total_time=$(echo "$total_time + $request_time" | bc)
echo "请求 $i: $request_time 秒"
sleep 1
done
avg_time=$(echo "scale=3; $total_time / 10" | bc)
echo "平均响应时间: $avg_time 秒"
echo "服务器: {{ ansible_host }}, 平均响应时间: $avg_time 秒" >> /tmp/benchmark_results.txt
args:
executable: /bin/bash
register: benchmark_result
- name: 显示测试结果
debug:
msg: "{{ benchmark_result.stdout_lines[-3:] }}"
- name: 汇总性能报告
hosts: localhost
gather_facts: no
tasks:
- name: 收集所有服务器结果
shell: |
# 从所有服务器收集结果
for i in {101..200}; do
ssh root@192.168.1.$i "cat /tmp/benchmark_results.txt 2>/dev/null || echo '服务器 192.168.1.$i 测试失败'" >> /tmp/all_results.txt
done
# 分析结果
echo "=== 集群性能测试报告 ==="
echo "测试时间: $(date)"
echo ""
grep "平均响应时间" /tmp/all_results.txt | sort -k3 -n | head -5 > /tmp/top5.txt
grep "平均响应时间" /tmp/all_results.txt | sort -k3 -n | tail -5 > /tmp/bottom5.txt
echo "响应最快的前5台服务器:"
cat /tmp/top5.txt
echo ""
echo "响应最慢的后5台服务器:"
cat /tmp/bottom5.txt
echo ""
# 计算平均值
avg=$(grep "平均响应时间" /tmp/all_results.txt | awk -F': ' '{sum+=$2; count++} END {if(count>0) print sum/count}')
echo "集群平均响应时间: ${avg:-N/A} 秒"
# 统计成功率
total=$(grep -c "平均响应时间" /tmp/all_results.txt)
failed=$(grep -c "测试失败" /tmp/all_results.txt)
success_rate=$(echo "scale=2; $total / 100 * 100" | bc)
echo "测试成功率: $success_rate% ($total/100)"
register: report
- name: 显示完整报告
debug:
msg: "{{ report.stdout }}"
7. 总结
通过本文的完整方案,我们实现了一个从零到百的千问3.5-27B集群自动化部署系统。让我们回顾一下这个方案的核心价值:
7.1 方案优势总结
- 效率提升:从手动单台部署到自动化批量部署,部署100台服务器的时间从数周缩短到几小时
- 一致性保障:通过Ansible的幂等性,确保每台服务器的环境完全一致,避免"环境差异"问题
- 可维护性:模块化的角色设计,使得后续更新、扩展变得非常简单
- 可扩展性:支持动态添加新服务器,轻松扩展集群规模
- 错误处理:完善的错误处理和重试机制,确保部署过程的可靠性
7.2 关键实践要点
在实际使用这套方案时,有几个关键点需要注意:
- 网络优化:模型文件通常很大,建议在局域网内搭建模型缓存服务器,避免每台服务器都从外网下载
- 分批部署:根据网络带宽和存储性能,合理控制并行部署的数量
- 监控告警:部署完成后,建议集成到现有的监控系统中,实时掌握集群状态
- 版本控制:将Ansible剧本纳入版本控制系统,方便团队协作和回滚
7.3 后续优化方向
虽然我们已经实现了一个完整的自动化部署方案,但仍有优化空间:
- 性能优化:可以考虑集成vLLM等推理优化框架,提升服务性能
- 高可用设计:增加负载均衡和故障转移机制
- 自动扩缩容:基于监控指标自动调整集群规模
- 蓝绿部署:实现零停机更新
7.4 开始你的自动化之旅
无论你是要部署10台还是1000台服务器,自动化都是必经之路。本文提供的方案是一个完整的起点,你可以根据自己的实际需求进行调整和扩展。
记住,自动化不是一蹴而就的,而是一个持续改进的过程。从最简单的脚本开始,逐步完善,最终构建出适合自己业务场景的自动化体系。
现在,拿起这个方案,开始你的百台GPU服务器部署之旅吧!你会发现,原本繁琐复杂的部署工作,现在只需要几条命令就能轻松搞定。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐


所有评论(0)