RexUniNLU在Ubuntu服务器上的高可用部署方案
如果你正在寻找一个能处理多种中文自然语言理解任务的模型,比如从一段新闻里抽取出人名、地名,或者判断一段评论是正面还是负面,RexUniNLU很可能就是你需要的那个“瑞士军刀”。它基于SiamesePrompt框架,一个模型就能搞定命名实体识别、关系抽取、情感分类等十几种任务,而且支持零样本学习,不用针对每个任务都去专门训练,用起来相当灵活。
但好东西往往也意味着更大的计算开销。当你打算把它从本地测试环境搬到线上,服务真实的用户请求时,问题就来了:单台服务器扛不住并发怎么办?服务突然挂了业务岂不是要中断?怎么知道它运行得好不好?今天,我们就来聊聊怎么在Ubuntu服务器上,给RexUniNLU搭建一个既扛得住压力、又不容易宕机的“高可用”生产环境。我会带你一步步走通容器化部署、负载均衡配置和监控告警设置,让你手里的这个强大模型,能真正稳定、可靠地跑起来。
1. 部署前准备:理清思路与备好工具
在开始敲命令之前,我们得先想清楚要建成什么样。所谓“高可用”,核心目标就两个:别宕机和别卡顿。为了实现这个目标,我们的方案会围绕几个关键点来展开:
- 容器化:用Docker把RexUniNLU模型和它的运行环境打包成一个标准化的“集装箱”。这样部署起来一致又快速,迁移也方便。
- 多副本与负载均衡:一个“集装箱”可能不够力,我们就多启动几个一模一样的。然后前面放一个“调度员”(负载均衡器),把用户请求合理地分发给这些副本,避免单个副本过载。
- 自动恢复:万一某个副本因为意外挂掉了,得有个“监工”能立刻发现,并自动重启一个新的副本顶上,确保服务整体不受影响。
- 健康检查与监控:给每个服务副本装上“体检仪”,持续检查它们是否健康。同时,还要有全局的“仪表盘”,能实时看到CPU、内存、请求延迟等关键指标,出了问题能及时报警。
基于这个思路,我们选择一套在云原生领域非常成熟和流行的技术组合:Docker 负责容器化,Docker Compose 负责编排多个服务,Nginx 做负载均衡器,再配合一些脚本和基础的系统监控工具。这套方案足够应对大多数中小规模的生产场景,而且理解和实施起来相对直接。
接下来,请确保你有一台或多台安装好 Ubuntu 20.04 LTS 或 22.04 LTS 的服务器,并拥有sudo权限。我们将从安装基础工具开始。
2. 基础环境搭建:安装Docker与Nginx
首先,我们需要在Ubuntu服务器上安装Docker引擎和Nginx。打开终端,依次执行以下命令。
更新系统软件包列表并安装一些必要的工具:
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
添加Docker的官方GPG密钥和软件源:
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
安装Docker引擎:
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
安装完成后,将当前用户加入docker组,这样以后就不用每次都加sudo来运行docker命令了(操作后需要退出终端重新登录生效):
sudo usermod -aG docker $USER
验证Docker安装是否成功:
docker --version
接下来安装Nginx,它将作为我们的反向代理和负载均衡器:
sudo apt-get install -y nginx
安装完成后,可以先启动Nginx并设置开机自启:
sudo systemctl start nginx
sudo systemctl enable nginx
现在,用浏览器访问你的服务器IP地址,应该能看到Nginx的欢迎页面,这说明基础环境已经就绪。
3. 容器化RexUniNLU服务
我们的核心任务是把RexUniNLU模型服务跑在Docker容器里。为了管理方便,我们使用Docker Compose来定义和运行多容器应用。如果没有安装,请先安装它:
sudo apt-get install -y docker-compose-plugin
接下来,创建一个项目目录,比如rexuninlu-ha,并在里面组织我们的文件。
mkdir -p ~/rexuninlu-ha && cd ~/rexuninlu-ha
3.1 编写模型服务应用代码
首先,我们需要一个简单的Python应用来加载RexUniNLU模型并提供HTTP API。创建一个名为app.py的文件:
# app.py
from flask import Flask, request, jsonify
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
import logging
import sys
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
app = Flask(__name__)
# 全局变量,用于缓存模型pipeline
nlp_pipeline = None
def load_model():
"""加载RexUniNLU模型"""
global nlp_pipeline
try:
logger.info("开始加载RexUniNLU模型...")
# 使用零样本通用自然语言理解任务
# 模型ID来自魔搭社区: iic/nlp_deberta_rex-uninlu_chinese-base
nlp_pipeline = pipeline(Tasks.siamese_uie, 'iic/nlp_deberta_rex-uninlu_chinese-base')
logger.info("RexUniNLU模型加载成功!")
except Exception as e:
logger.error(f"模型加载失败: {e}")
sys.exit(1)
@app.route('/health', methods=['GET'])
def health_check():
"""健康检查端点"""
if nlp_pipeline is not None:
return jsonify({"status": "healthy", "model": "RexUniNLU"}), 200
else:
return jsonify({"status": "unhealthy"}), 503
@app.route('/predict', methods=['POST'])
def predict():
"""模型预测主接口"""
if nlp_pipeline is None:
return jsonify({"error": "Model not loaded"}), 500
try:
data = request.get_json()
text = data.get('text', '')
schema = data.get('schema', {})
if not text:
return jsonify({"error": "Text input is required"}), 400
if not schema:
return jsonify({"error": "Schema is required"}), 400
logger.info(f"收到预测请求,文本长度: {len(text)}")
# 调用模型进行推理
result = nlp_pipeline(input=text, schema=schema)
return jsonify({"result": result})
except Exception as e:
logger.error(f"预测过程中发生错误: {e}")
return jsonify({"error": str(e)}), 500
if __name__ == '__main__':
# 先加载模型
load_model()
# 启动Flask应用,监听所有网络接口
app.run(host='0.0.0.0', port=5000, debug=False)
这个应用做了几件事:
- 使用Flask创建了一个Web服务。
- 在启动时加载RexUniNLU模型(基于ModelScope的pipeline)。
- 提供了两个API端点:
/health用于健康检查,/predict用于接收文本和schema进行推理。 - 加入了基本的错误处理和日志记录。
3.2 创建Dockerfile
接下来,我们需要一个Dockerfile来定义如何构建这个Python应用的镜像。创建Dockerfile文件:
# Dockerfile
# 使用官方Python精简版镜像作为基础
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 安装系统依赖,包括一些编译可能需要的工具
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
g++ \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件并安装
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 复制应用代码
COPY app.py .
# 暴露应用端口
EXPOSE 5000
# 定义容器启动命令
CMD ["python", "app.py"]
3.3 创建requirements.txt
创建requirements.txt文件,列出Python依赖:
# requirements.txt
flask>=2.0.0
modelscope>=1.0.0
transformers>=4.10.0
torch>=1.9.0
3.4 创建Docker Compose配置文件
现在,我们来创建核心的docker-compose.yml文件,它将定义我们的服务集群,包括多个RexUniNLU服务副本和一个用于负载均衡的Nginx。
# docker-compose.yml
version: '3.8'
services:
# RexUniNLU模型服务,我们启动3个副本
rexuninlu-app:
build: .
# 取消下面一行的注释,如果你的服务器有NVIDIA GPU并安装了nvidia-docker
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: all
# capabilities: [gpu]
environment:
- PYTHONUNBUFFERED=1
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
replicas: 3
restart_policy:
condition: on-failure
delay: 5s
networks:
- rex-net
# Nginx作为负载均衡器
nginx-lb:
image: nginx:alpine
ports:
- "80:80" # 将宿主机的80端口映射到容器的80端口
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro # 挂载自定义的Nginx配置
depends_on:
- rexuninlu-app
networks:
- rex-net
# 定义自定义网络,方便服务间通信
networks:
rex-net:
driver: bridge
这个配置的关键点:
rexuninlu-app服务会基于当前目录的Dockerfile构建镜像,并启动3个副本。- 配置了
healthcheck,Docker会定期检查/health接口,不健康的容器会被标记。 - 设置了
restart_policy,如果容器失败,Docker会在5秒后尝试重启它。 nginx-lb服务使用官方Nginx镜像,并挂载我们自定义的配置文件。
3.5 配置Nginx负载均衡
创建nginx.conf文件,这是Nginx的配置文件:
# nginx.conf
events {
worker_connections 1024;
}
http {
upstream rexuninlu_backend {
# 使用Docker Compose的服务名进行负载均衡
# Nginx会自动解析到当前健康的容器IP
server rexuninlu-app:5000;
server rexuninlu-app:5000;
server rexuninlu-app:5000;
# 可以添加更多,但通常与docker-compose中replicas数量一致即可
# 默认使用轮询(round-robin)策略
}
server {
listen 80;
server_name _;
location / {
proxy_pass http://rexuninlu_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 增加超时时间,模型推理可能较慢
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 120s;
}
# 可选:提供一个状态查看页面
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
}
这个配置定义了一个名为rexuninlu_backend的上游服务器组,里面包含了三个相同的后端服务地址(对应Docker Compose中的三个副本)。Nginx会将到达80端口的请求,以轮询的方式分发给这三个后端。
4. 启动与验证高可用集群
所有文件准备就绪后,你的项目目录结构应该如下所示:
rexuninlu-ha/
├── app.py
├── Dockerfile
├── requirements.txt
├── docker-compose.yml
└── nginx.conf
现在,在项目根目录下,使用一条命令启动整个集群:
docker compose up -d
-d参数表示在后台运行。Docker Compose会先构建rexuninlu-app的镜像,然后按配置启动所有服务。
等待几分钟,让镜像构建和容器启动完成。你可以使用以下命令查看服务状态:
docker compose ps
你应该看到rexuninlu-app有3个实例在运行,nginx-lb有1个实例在运行。
查看特定服务的日志,确保模型加载成功:
docker compose logs rexuninlu-app
在日志中寻找“RexUniNLU模型加载成功!”的字样。
4.1 验证服务可用性
首先,直接测试后端应用的健康检查接口(通过一个服务副本):
# 获取任意一个rexuninlu-app容器的ID
CONTAINER_ID=$(docker ps --filter "name=rexuninlu-ha-rexuninlu-app" --format "{{.ID}}" | head -n 1)
# 在容器内执行curl命令
docker exec $CONTAINER_ID curl -s http://localhost:5000/health | python3 -m json.tool
应该返回{"status": "healthy", "model": "RexUniNLU"}。
然后,测试通过Nginx负载均衡器的接口:
curl -s http://localhost/health | python3 -m json.tool
同样应该返回健康状态。这个请求会先到达Nginx,再由Nginx转发给后端的某个RexUniNLU实例。
4.2 进行模型推理测试
现在,让我们发送一个真实的预测请求。创建一个测试文件test_request.json:
{
"text": "1944年毕业于北大的名古屋铁道会长谷口清太郎等人在日本积极筹资,共筹款2.7亿日元,参加捐款的日本企业有69家。",
"schema": {
"人物": null,
"地理位置": null,
"组织机构": null
}
}
使用curl命令发送POST请求:
curl -X POST http://localhost/predict \
-H "Content-Type: application/json" \
-d @test_request.json | python3 -m json.tool
如果一切正常,你将收到一个包含抽取出的实体信息的JSON响应。多执行几次这个命令,由于Nginx的轮询策略,请求会被分发到不同的后端实例上(可以通过查看不同容器的日志来验证)。

4.3 模拟故障转移
高可用的核心能力是容错。我们来模拟一个后端实例宕机的情况。
-
手动停止一个后端容器:
# 停止其中一个容器 docker stop rexuninlu-ha-rexuninlu-app-1(容器名可能略有不同,请用
docker ps查看实际名称) -
观察Docker Compose的反应:
docker compose ps稍等片刻(取决于
healthcheck的检测间隔和restart_policy),你应该会看到Docker尝试重启那个失败的容器,或者因为健康检查不通过而将其标记为不健康。同时,Nginx的上游配置会自动将流量从失败的后端移除。 -
继续发送测试请求:
curl -X POST http://localhost/predict \ -H "Content-Type: application/json" \ -d @test_request.json服务应该仍然能够正常响应,因为另外两个健康的实例还在工作。这就是高可用带来的好处:单点故障不影响整体服务。
-
恢复测试:
docker start rexuninlu-ha-rexuninlu-app-1等待其通过健康检查后,Nginx会自动将其重新加入负载均衡池。
5. 生产环境调优与监控建议
上面的方案搭建了一个可用的高可用基础架构。但要用于真正的生产环境,还需要考虑更多。
5.1 性能与资源调优
- GPU支持:如果服务器有NVIDIA GPU,可以显著加速模型推理。需要先在宿主机安装NVIDIA驱动和
nvidia-docker工具包。然后在docker-compose.yml中为rexuninlu-app服务取消注释关于GPU的deploy.resources部分。 - 容器资源限制:在
docker-compose.yml中,可以为服务设置CPU和内存限制,防止某个容器耗尽所有资源。services: rexuninlu-app: # ... deploy: resources: limits: cpus: '2.0' memory: 4G reservations: cpus: '1.0' memory: 2G - 模型加载优化:首次启动时下载模型可能会很慢。可以考虑提前将模型文件下载到宿主机,然后在Dockerfile中使用
COPY指令复制到镜像中,或者启动容器时通过volumes挂载模型目录。 - Nginx调优:根据实际并发量和请求处理时间,调整
nginx.conf中的worker_connections、超时时间(proxy_connect_timeout,proxy_read_timeout),并可以考虑启用缓存或调整负载均衡算法(如least_conn最少连接)。
5.2 监控与告警
“高可用”离不开有效的监控。除了Docker自带的docker stats命令,建议集成更专业的监控系统。
- 基础监控:使用
Prometheus+Grafana组合。- 为Flask应用添加
/metrics端点(可以使用prometheus-flask-exporter库)。 - 使用
cAdvisor监控容器资源使用情况(CPU、内存、网络IO)。 - 使用
Node Exporter监控宿主机指标。 - 在Grafana中创建仪表盘,可视化QPS(每秒查询率)、响应延迟、错误率、容器资源使用率等。
- 为Flask应用添加
- 日志集中管理:使用
ELK Stack(Elasticsearch, Logstash, Kibana) 或Loki来收集和查看所有容器的日志,便于问题排查。 - 告警:在Prometheus中设置告警规则(Alerting Rules),当响应时间超过阈值、错误率升高或容器持续重启时,通过
Alertmanager发送通知到邮件、Slack或钉钉。
5.3 进一步提升可用性
- 多节点部署:当前的方案运行在单台服务器上,这台服务器本身仍是单点。真正的生产高可用需要多台服务器(节点)。可以考虑使用
Docker Swarm或Kubernetes来管理跨多个节点的容器集群,这样即使一台物理机宕机,服务也会在其他节点上重新调度运行。 - 数据库与状态:如果未来你的应用需要存储状态(如用户会话、任务队列),需要将这些有状态的服务(如Redis、PostgreSQL)也配置为高可用模式,例如使用主从复制、哨兵或集群方案。
- 外部负载均衡与域名:目前Nginx监听在服务器的80端口。在实际生产环境中,你可能有多个这样的服务节点。你需要在它们前面再配置一个外部的负载均衡器(如云服务商提供的LB、HAProxy等),并配置域名DNS解析,实现流量在多个节点间的分发和故障转移。
6. 总结
走完这一趟,我们从零开始,在Ubuntu服务器上为RexUniNLU模型搭建了一个具备基本高可用能力的服务架构。通过Docker容器化,我们解决了环境一致性问题;通过多副本和Nginx负载均衡,我们提升了服务的吞吐量和并发能力;通过健康检查与重启策略,我们实现了服务的自动恢复。
这套基于Docker Compose的方案,结构清晰,配置直观,非常适合作为从单机部署迈向生产可用的第一步。它让你能在一个可控的环境里,充分理解高可用涉及的各个组件是如何协同工作的。当然,就像最后一部分提到的,要应对更大规模、更严苛的生产需求,道路还很长,需要考虑分布式集群、更完善的监控和更自动化的运维。
不过,技术方案的演进总是循序渐进的。先把眼前这个架构跑稳、吃透,理解每一个配置项背后的意义,监控好它的运行状态。当你对流量模式、性能瓶颈有了更具体的感知后,再去探索Swarm、Kubernetes这些更强大的工具,就会更有方向。希望这份指南能帮你迈出坚实的第一步,让你手中的RexUniNLU模型,能够更可靠、更高效地服务于你的业务。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。






