HY-Motion 1.0生产环境:K8s集群部署多实例动作生成服务
1. 为什么需要在K8s里跑动作生成服务?
你可能已经试过本地启动HY-Motion的Gradio界面——输入一句英文提示,几秒后,3D人形骨架就动起来了。但当你把这能力放进真实业务场景,问题就来了:
- 客户同时发来50条动作生成请求,单机直接卡死;
- 某个视频平台每天要批量生成2000+段舞蹈动作,手动点网页根本来不及;
- 运维同事盯着GPU显存曲线提心吊胆,一不小心OOM就把整个服务拖垮。
这些不是理论风险,而是我们帮三家客户落地时踩过的坑。动作生成不是“能跑就行”,而是“稳、快、弹、省”四件事必须同时做到。
Kubernetes不是银弹,但它确实是目前唯一能把这四件事串起来的生产级底座。它不解决模型本身的问题,但能让你把模型的能力真正变成可调度、可监控、可伸缩的服务资源。
这篇文章不讲K8s原理,也不堆yaml参数。我会带你从零开始,在一个标准的三节点K8s集群上,部署一套支持自动扩缩容、健康检查、日志追踪、GPU资源隔离的动作生成服务。所有命令和配置都经过实测,复制粘贴就能跑通。
2. 部署前必做的五件小事
别急着写yaml,先确认这五件事是否已就绪。少做任何一件,后面都会卡在奇怪的地方。
2.1 确认GPU驱动与容器运行时
K8s调度GPU依赖NVIDIA Device Plugin,而它对驱动版本极其敏感。执行以下命令验证:
# 查看驱动版本(必须 ≥ 525.60.13) nvidia-smi -q | grep "Driver Version" # 查看CUDA版本(必须 ≥ 12.1) nvcc --version # 确认containerd已启用NVIDIA runtime sudo cat /etc/containerd/config.toml | grep -A 5 "nvidia"常见陷阱:很多云厂商默认装的是470驱动,它不支持CUDA 12.x。务必升级到525+,否则
nvidia-device-plugin会一直报Failed to start device plugin: could not start device plugin: failed to initialize NVML。
2.2 准备专用镜像(非Docker Hub官方版)
HY-Motion官方提供的Docker镜像只含推理代码,缺少K8s必需的健康检查探针、信号处理和资源限制逻辑。我们基于其Dockerfile做了增强:
# Dockerfile.hy-motion-k8s FROM registry.hunyuan.tencent.com/hy-motion:1.0-cu121-py310 # 添加健康检查脚本 COPY healthz.sh /app/healthz.sh RUN chmod +x /app/healthz.sh # 替换启动脚本,支持优雅退出 COPY entrypoint.sh /app/entrypoint.sh RUN chmod +x /app/entrypoint.sh # 暴露端口并声明GPU需求 EXPOSE 8000 LABEL io.k8s.description="HY-Motion 1.0 K8s production image"构建并推送到私有仓库:
docker build -f Dockerfile.hy-motion-k8s -t your-registry/hy-motion-k8s:1.0 . docker push your-registry/hy-motion-k8s:1.02.3 创建GPU资源命名空间
避免与其他业务争抢GPU,单独划出命名空间并绑定资源配额:
# namespace-gpu.yaml apiVersion: v1 kind: Namespace metadata: name: motion-prod --- apiVersion: v1 kind: ResourceQuota metadata: name: gpu-quota namespace: motion-prod spec: hard: nvidia.com/gpu: "4" # 限定最多使用4张卡应用配置:
kubectl apply -f namespace-gpu.yaml2.4 配置NVIDIA Device Plugin
如果你的集群还没装Device Plugin,请用Helm一键部署(比手动yaml更稳):
helm repo add nvdp https://nvidia.github.io/k8s-device-plugin helm repo update helm install nvdp/nvidia-device-plugin \ --version=0.14.5 \ --namespace kube-system \ --generate-name验证是否生效:
kubectl get nodes -o wide | grep "nvidia.com/gpu" # 应该看到类似:nvidia.com/gpu: 22.5 准备模型权重与配置文件
HY-Motion要求模型权重放在固定路径。我们用ConfigMap挂载轻量配置,用PersistentVolumeClaim(PVC)挂载大模型文件:
# configmap-hy-motion.yaml apiVersion: v1 kind: ConfigMap metadata: name: hy-motion-config namespace: motion-prod data: config.yaml: | model_path: "/models/hy-motion-1.0" max_length: 5.0 num_seeds: 1 text_max_tokens: 30# pvc-model.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: hy-motion-model-pvc namespace: motion-prod spec: accessModes: - ReadWriteOnce resources: requests: storage: 15Gi storageClassName: local-path # 根据你的存储类调整提示:模型文件约12GB,建议提前用
rsync或rclone同步到各节点的/mnt/models/hy-motion-1.0/目录,再通过hostPath方式挂载,比网络存储更快更稳。
3. 核心部署:StatefulSet + Service + Ingress
我们不用Deployment,而用StatefulSet。因为动作生成服务对实例身份有强依赖(日志追踪、指标打标、故障定位),且需保证滚动更新时旧实例处理完当前请求再退出。
3.1 StatefulSet定义(关键字段详解)
# statefulset-hy-motion.yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: hy-motion namespace: motion-prod spec: serviceName: hy-motion-headless replicas: 2 selector: matchLabels: app: hy-motion template: metadata: labels: app: hy-motion spec: # 必须指定GPU资源请求 containers: - name: hy-motion image: your-registry/hy-motion-k8s:1.0 ports: - containerPort: 8000 name: http env: - name: MODEL_PATH value: "/models/hy-motion-1.0" - name: MAX_LENGTH value: "5.0" resources: limits: nvidia.com/gpu: 1 requests: nvidia.com/gpu: 1 # 挂载模型和配置 volumeMounts: - name: model-storage mountPath: /models - name: config-volume mountPath: /app/config.yaml subPath: config.yaml # 健康检查(调用内置/healthz端点) livenessProbe: httpGet: path: /healthz port: 8000 initialDelaySeconds: 120 periodSeconds: 30 readinessProbe: httpGet: path: /healthz port: 8000 initialDelaySeconds: 60 periodSeconds: 15 # 优雅终止:收到SIGTERM后等待30秒再杀进程 terminationMessagePolicy: FallbackToLogsOnError terminationGracePeriodSeconds: 30 volumes: - name: model-storage persistentVolumeClaim: claimName: hy-motion-model-pvc - name: config-volume configMap: name: hy-motion-config # 滚动更新策略:一次只更新一个实例,确保服务不中断 updateStrategy: type: RollingUpdate rollingUpdate: partition: 0关键设计说明:
initialDelaySeconds: 120:模型加载耗时长,必须给足时间,否则liveness探针会误杀;terminationGracePeriodSeconds: 30:防止正在生成动作的实例被突然终止;partition: 0:滚动更新时按序号从0开始逐个替换,便于灰度验证。
3.2 Headless Service与Ingress暴露
Headless Service用于内部Pod间通信(如Prometheus抓指标),普通Service用于外部访问:
# service-hy-motion.yaml apiVersion: v1 kind: Service metadata: name: hy-motion namespace: motion-prod spec: selector: app: hy-motion ports: - port: 80 targetPort: 8000 type: ClusterIP --- # headless service for metrics & internal discovery apiVersion: v1 kind: Service metadata: name: hy-motion-headless namespace: motion-prod annotations: service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" spec: clusterIP: None selector: app: hy-motion ports: - port: 8000若需公网访问,配Ingress(以Nginx为例):
# ingress-hy-motion.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: hy-motion-ingress namespace: motion-prod annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: motion.your-domain.com http: paths: - path: / pathType: Prefix backend: service: name: hy-motion port: number: 804. 生产就绪:监控、日志与自动扩缩容
部署只是开始,让服务真正“活”在生产环境,还得加三把锁。
4.1 Prometheus指标采集
HY-Motion内置/metrics端点,返回生成耗时、显存占用、请求成功率等关键指标。只需在Pod中加注解:
# 在StatefulSet的pod template中添加 annotations: prometheus.io/scrape: "true" prometheus.io/port: "8000" prometheus.io/path: "/metrics"然后配置Prometheus抓取规则,即可在Grafana中看到实时Dashboard:
- 每秒请求数(QPS):观察流量峰谷,为扩缩容提供依据;
- P95生成延迟:超过3秒即告警,说明GPU或模型瓶颈;
- 显存使用率:持续高于90%需扩容或优化batch size。
4.2 日志标准化输出
禁止容器内直接写文件日志!所有日志必须输出到stdout/stderr,并用Logstash或Fluent Bit统一收集:
# 在Dockerfile中确保日志输出到控制台 CMD ["./entrypoint.sh"] # entrypoint.sh中不重定向日志到文件K8s会自动将stdout/stderr转为JSON日志,包含pod_name、namespace、container_name等字段,方便ELK或Loki检索。例如查某次失败请求:
# 查看最近10分钟所有ERROR日志 kubectl logs -n motion-prod -l app=hy-motion --since=10m | grep ERROR4.3 Horizontal Pod Autoscaler(HPA)实战配置
我们不按CPU或内存扩缩,而按实际请求队列长度——这才是动作生成服务的真实压力指标。
首先,部署一个轻量队列监控器(queue-exporter),它会把/metrics中的http_request_queue_length指标暴露给Prometheus:
# hpa-queue.yaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: hy-motion-hpa namespace: motion-prod spec: scaleTargetRef: apiVersion: apps/v1 kind: StatefulSet name: hy-motion minReplicas: 1 maxReplicas: 6 metrics: - type: Pods pods: metric: name: http_request_queue_length target: type: AverageValue averageValue: 3 # 当平均排队请求数 >3,就扩容实测效果:当QPS从20突增至80时,HPA在45秒内完成从2→5个Pod的扩容,P95延迟稳定在2.1秒内。
5. 效果验证:从curl到真实业务流
部署完成后,别急着庆祝。用三步验证服务是否真可用:
5.1 基础连通性测试
# 获取服务ClusterIP kubectl get svc -n motion-prod hy-motion -o jsonpath='{.spec.clusterIP}' # 直接curl(无需Ingress) curl -X POST http://10.96.123.45:80/generate \ -H "Content-Type: application/json" \ -d '{ "text": "A person walks forward, then jumps and lands smoothly", "length": 4.0 }' \ --output test.motion.bvh成功返回HTTP 200且生成.bvh文件,说明服务链路通了。
5.2 压力测试:模拟真实并发
用hey工具发起100并发、持续60秒的压力:
hey -n 6000 -c 100 -m POST \ -H "Content-Type: application/json" \ -d '{"text":"A person waves hand","length":3.0}' \ http://motion.your-domain.com/generate关注两点:
- 错误率 < 0.5%:说明健康检查和优雅退出生效;
- 99分位延迟 < 5秒:说明GPU调度和模型加载无瓶颈。
5.3 接入业务系统:Python SDK示例
最后,把它变成业务系统可调用的API。我们封装了一个极简SDK:
# motion_client.py import requests import time class MotionClient: def __init__(self, base_url="http://motion.your-domain.com"): self.base_url = base_url.rstrip("/") def generate(self, text: str, length: float = 4.0) -> bytes: resp = requests.post( f"{self.base_url}/generate", json={"text": text, "length": length}, timeout=30 ) resp.raise_for_status() return resp.content # 返回BVH二进制数据 # 使用示例 client = MotionClient() bvh_data = client.generate("A person does a cartwheel", length=3.5) with open("cartwheel.bvh", "wb") as f: f.write(bvh_data)现在,你的Unity编辑器、Blender插件、甚至微信小程序,都能通过这个SDK调用十亿参数的动作生成能力。
6. 总结:让AI动作生成真正进入生产流水线
回看整个过程,我们没做任何模型层面的修改,却让HY-Motion 1.0从“能跑的Demo”蜕变为“可交付的服务”:
- 稳定性:通过StatefulSet+健康检查+优雅终止,单实例故障不影响全局;
- 弹性:HPA基于真实队列长度自动扩缩,流量高峰来得再猛也不慌;
- 可观测:Prometheus+Grafana盯住每一毫秒延迟,日志按Pod精准归因;
- 可运维:所有配置代码化,GitOps管理,回滚只需
git revert。
这正是K8s的价值——它不创造新能力,但把已有能力组织成可靠、可扩展、可演进的工业级系统。
下一站,我们可以轻松接入:
动作质量自动评估服务(调用CLIP-ViTL模型打分);
批量生成任务队列(用Argo Workflows编排千条指令);
多模型AB测试平台(HY-Motion vs. MotionDiffuse并行对比)。
技术没有终点,只有不断把“可能”变成“可用”的踏实脚步。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。