NVIDIA Kimodo 运动学动作扩散模型——文本生成 3D 人体动作,本地部署 + Blender 集成全流程。
记录时间:2026-08-25|适用版本:Kimodo (main 分支) + Blender 5.0.1|环境:Windows + GTX 1070 Ti 8GB
一、背景与原理
什么是 Kimodo
Kimodo 是 NVIDIA 发布的运动学动作扩散模型(Kinematic Motion Diffusion),使用 700 小时光学动捕数据训练,核心能力是从文本提示生成 3D 人体动作。
- 输入:一段英文动作描述(如 “A person walks forward.”)
- 输出:NPZ(完整动作数据)+ BVH(SOMA 骨架动画文件)
- 模型:
nvidia/Kimodo-SOMA-RP-v1.1(约 1.1GB)
为什么需要量化编码器
Kimodo 官方使用 Meta Llama3-8B 作为文本编码器,该模型在 HuggingFace 上是 gated 模型——需要申请授权并获取 token 才能下载。本教程通过使用社区预量化的 NF4 模型 Aero-Ex/KIMODO-Meta3_llm2vec_NF4(约 4.4GB)替代官方编码器,绕过授权限制,同时大幅降低显存需求。
显存要求
| 模式 | 显存需求 | 适用显卡 |
|---|---|---|
| GPU 编码(量化后) | 约 3GB 编码 + 模型本身 | 12GB+ 显卡 |
| CPU 编码(本教程) | 约 2GB(仅模型) | 8GB 显卡即可 |
本机 GTX 1070 Ti 8GB 显存不足 12GB,通过
TEXT_ENCODER_DEVICE=cpu将文本编码放到 CPU 上运行,GPU 仅负责扩散模型推理。
二、环境要求
硬件
| 组件 | 最低要求 | 本机配置 |
|---|---|---|
| GPU | NVIDIA 8GB+(CUDA 12.4 兼容) | GTX 1070 Ti 8GB |
| 内存 | 16GB+ | 64GB DDR4 |
| 磁盘 | 10GB+ 可用空间 | D 盘 148GB |
| CPU | 多核(CPU 编码时影响速度) | i7-8700 |
软件
| 组件 | 版本 | 用途 |
|---|---|---|
| Python | 3.11.x(不要用 3.12+) | 运行环境 |
| Git | 任意 | 克隆仓库 |
| CUDA 驱动 | 525+(支持 CUDA 12.4) | GPU 推理 |
| Blender | 4.0+(本机 5.0.1) | BVH 导入编辑 |
| Node.js | 可选(viser Web UI 需要) | 前端构建 |
Python 版本注意:Kimodo 依赖的部分库(如 bitsandbytes)在 Python 3.12+ 上兼容性差,强烈建议使用 Python 3.11。
三、安装步骤
第 1 步:安装 Python 3.11
# 下载 Python 3.11.9
curl -L -o python311-installer.exe "https://www.python.org/ftp/python/3.11.9/python-3.11.9-amd64.exe"
# 静默安装(不加入系统 PATH,避免与现有 Python 冲突)
python311-installer.exe /quiet InstallAllUsers=0 PrependPath=0 TargetDir="C:Users<用户名>AppDataLocalProgramsPythonPython311"
第 2 步:克隆 Kimodo 仓库
# 直连 GitHub(国内可能超时)
cd D:
git clone https://github.com/nv-tlabs/kimodo.git
# 国内镜像方案(推荐)
git clone --depth 1 https://ghfast.top/https://github.com/nv-tlabs/kimodo.git
坑 1:GitHub 直连超时 — 国内网络直连 GitHub 经常超时。使用
ghfast.top镜像或配置 Git 代理。--depth 1浅克隆只取最新提交,大幅减少下载量。
第 3 步:创建虚拟环境
# 用 Python 3.11 创建虚拟环境
"C:/Users/<用户名>/AppData/Local/Programs/Python/Python311/python.exe" -m venv "D:/kimodo/env"
# 验证
"D:/kimodo/env/Scripts/python.exe" --version
# 应输出: Python 3.11.x
第 4 步:安装 PyTorch(CUDA 12.4)
"D:/kimodo/env/Scripts/pip.exe" install torch --index-url https://download.pytorch.org/whl/cu124
验证 CUDA 可用:
"D:/kimodo/env/Scripts/python.exe" -c "import torch; print(torch.__version__, torch.cuda.is_available(), torch.cuda.get_device_name(0))"
# 应输出: 2.6.0+cu124 True NVIDIA GeForce GTX 1070 Ti
坑 2:PyTorch 包约 2.5GB — 下载时间较长(10-30 分钟取决于网速)。如果超时,重试即可,pip 会断点续传。
第 5 步:安装 Kimodo 依赖
# 安装 wheel 和 setuptools(必需)
"D:/kimodo/env/Scripts/pip.exe" install wheel setuptools
# 跳过 MotionCorrection C++ 编译安装基础包
cd D:/kimodo
set SKIP_MOTION_CORRECTION_IN_SETUP=1
"D:/kimodo/env/Scripts/pip.exe" install -e . --no-build-isolation
坑 3:MotionCorrection 编译需要 MSVC + CMake —
setup.py默认编译 MotionCorrection C++ 扩展,需要 Visual Studio 2022 + CMake。本机只有 VS2017,缺少 MSVC,因此用SKIP_MOTION_CORRECTION_IN_SETUP=1跳过。后处理功能会被关闭,但不影响核心的动作生成。
坑 4:不要直接
pip install -e ".[all]"—[all]包含 viser fork 和 SOMA-X 的 git 依赖,会从 GitHub 拉取,国内极易卡死。应分步安装。
第 6 步:安装 bitsandbytes
"D:/kimodo/env/Scripts/pip.exe" install -U "bitsandbytes>=0.46.1"
第 7 步:安装 viser fork(通过镜像)
# 通过镜像安装 viser fork
GIT_SSL_NO_VERIFY=1 "D:/kimodo/env/Scripts/pip.exe" install --no-deps "viser @ git+https://ghfast.top/https://github.com/nv-tlabs/kimodo-viser.git@c60bb86bf8a865272815c4a6be97fd8f9631d910"
安装 viser 依赖:
"D:/kimodo/env/Scripts/pip.exe" install "nodeenv<2.0.0,>=1.9.1" "requests<3.0.0,>=2.0.0" "yourdfpy<1.0.0,>=0.0.53" "rich<15.0.0,>=13.3.3" "trimesh<5.0.0,>=3.21.7" "websockets<16.0.0,>=13.1" msgspec scikit-image matplotlib
坑 5:viser 依赖版本冲突 — SOMA-X 安装后可能升级 trimesh/rich/websockets 到不兼容版本。需重新安装 viser 要求的版本范围。
第 8 步:打 viser Windows 补丁
viser 的 _client_autobuild.py 在 Windows 上调用 npm/npx 时使用 POSIX 路径,会导致 Web UI 启动失败。需要打补丁改用 npm.cmd/npx.cmd。
创建 D:/kimodo/patch_viser.py:
"""
Patch viser/_client_autobuild.py for Windows so it uses npm.cmd / npx.cmd.
Idempotent. No-op on non-Windows.
"""
import re
import sys
from pathlib import Path
PATCH_MARKER = "# VISER_WIN_NPMCMD_PATCHED"
def patch_viser() -> int:
if sys.platform != "win32":
print("[patch_viser] Not on Windows, skipping.")
return 0
try:
import viser
except ImportError:
print("[patch_viser] viser not installed yet, skipping.")
return 0
autobuild_path = Path(viser.__file__).parent / "_client_autobuild.py"
if not autobuild_path.exists():
print(f"[patch_viser] File not found: {autobuild_path}")
return 1
src = autobuild_path.read_text(encoding="utf-8")
if PATCH_MARKER in src:
print("[patch_viser] Already patched.")
return 0
new = src
new, n1 = re.subn(
r'(node_bin_dir / "npx").exists()',
'(node_bin_dir / ("npx.cmd" if sys.platform == "win32" else "npx")).exists()',
new,
)
npm_line_re = re.compile(r'^( *)npm_path = node_bin_dir / "npm"s*$', re.MULTILINE)
def _inject(m: re.Match) -> str:
indent = m.group(1)
return (
f'{indent}npm_path = node_bin_dir / "npm"n'
f'{indent}if sys.platform == "win32":n'
f'{indent} _npm_cmd = node_bin_dir / "npm.cmd"n'
f'{indent} _npx_cmd = node_bin_dir / "npx.cmd"n'
f'{indent} if _npm_cmd.exists():n'
f'{indent} npm_path = _npm_cmdn'
f'{indent} if _npx_cmd.exists():n'
f'{indent} npx_path = _npx_cmd'
)
new, n2 = npm_line_re.subn(_inject, new, count=1)
if n1 == 0 and n2 == 0:
print("[patch_viser] No patch targets found.")
return 0
new = f"{PATCH_MARKER}n{new}"
autobuild_path.write_text(new, encoding="utf-8")
print(f"[patch_viser] Patched: {autobuild_path}")
return 0
if __name__ == "__main__":
sys.exit(patch_viser())
运行补丁:
cd D:/kimodo
"D:/kimodo/env/Scripts/python.exe" patch_viser.py
重要:每次重装/升级 viser 后都需要重新运行此补丁。脚本幂等,重复运行无副作用。
第 9 步:安装 SOMA-X(通过镜像)
# 先克隆到本地
cd D:
GIT_SSL_NO_VERIFY=1 git clone --depth 1 https://ghfast.top/https://github.com/NVlabs/SOMA-X.git
# 从本地路径安装
cd D:/SOMA-X
"D:/kimodo/env/Scripts/pip.exe" install -e . --no-build-isolation
坑 6:SOMA-X git 依赖卡死 — 直接
pip install py-soma-x @ git+...会因 GitHub 连接问题卡死 20+ 分钟。解决方案:先git clone到本地,再pip install -e .从本地安装。
第 10 步:验证所有导入
"D:/kimodo/env/Scripts/python.exe" -c "import viser; import kimodo; import bitsandbytes; print('All imports OK')"
四、下载模型文件
方案 A:huggingface-cli 下载(推荐,但需绕过沙箱)
set HF_ENDPOINT=https://hf-mirror.com
"D:/kimodo/env/Scripts/huggingface-cli.exe" download nvidia/Kimodo-SOMA-RP-v1.1 --local-dir D:/kimodo/models/Kimodo-SOMA-RP-v1.1
"D:/kimodo/env/Scripts/huggingface-cli.exe" download Aero-Ex/KIMODO-Meta3_llm2vec_NF4 --local-dir D:/kimodo/models/llm2vec-nf4
方案 B:curl 直接下载 LFS 文件(兜底方案)
# 1. 克隆仓库(跳过 LFS)
cd D:/kimodo/models
GIT_LFS_SKIP_SMUDGE=1 git clone https://hf-mirror.com/nvidia/Kimodo-SOMA-RP-v1.1
GIT_LFS_SKIP_SMUDGE=1 git clone https://hf-mirror.com/Aero-Ex/KIMODO-Meta3_llm2vec_NF4 llm2vec-nf4
# 2. 用 curl 下载 LFS 大文件
cd D:/kimodo/models/Kimodo-SOMA-RP-v1.1
curl -L -o model.safetensors "https://hf-mirror.com/nvidia/Kimodo-SOMA-RP-v1.1/resolve/main/model.safetensors"
cd D:/kimodo/models/llm2vec-nf4
curl -L -o model.safetensors "https://hf-mirror.com/Aero-Ex/KIMODO-Meta3_llm2vec_NF4/resolve/main/model.safetensors"
curl -L -o tokenizer.json "https://hf-mirror.com/Aero-Ex/KIMODO-Meta3_llm2vec_NF4/resolve/main/tokenizer.json"
坑 7:HuggingFace 连接超时 — 国内直连 HuggingFace 会超时。必须设置
HF_ENDPOINT=https://hf-mirror.com使用镜像。
模型目录结构
D:/kimodo/models/
├── Kimodo-SOMA-RP-v1.1/
│ ├── config.yaml
│ ├── model.safetensors # 约 1.1GB
│ └── stats/
│ └── motion/
│ ├── body/ (mean.npy, std.npy)
│ ├── global_root/ (mean.npy, std.npy)
│ └── local_root/ (mean.npy, std.npy)
└── llm2vec-nf4/
├── model.safetensors # 约 4.4GB
├── tokenizer.json # 约 16MB
└── ...
坑 9:模型目录名必须匹配 display_name —
CHECKPOINT_DIR环境变量指向模型根目录后,Kimodo 会用模型的display_name作为子目录名查找。如果目录名不匹配会报 “Model folder not found”。
五、源码改动(量化编码器支持)
改动 1:kimodo/model/load_model.py
在 TEXT_ENCODER_PRESETS 字典中新增三个量化预设:
TEXT_ENCODER_PRESETS = {
# 原始预设(需要 Llama3 gated 授权)
"llm2vec": {
"target": "kimodo.model.LLM2VecEncoder",
"kwargs": {
"base_model_name_or_path": "McGill-NLP/LLM2Vec-Meta-Llama-3-8B-Instruct-mntp",
"peft_model_name_or_path": "McGill-NLP/LLM2Vec-Meta-Llama-3-8B-Instruct-mntp-supervised",
"dtype": "bfloat16", "llm_dim": 4096, "device": "auto", "load_in_4bit": False,
},
},
# === 新增:NF4 预量化编码器(无需授权) ===
"llm2vec-nf4": {
"target": "kimodo.model.LLM2VecEncoder",
"kwargs": {
"base_model_name_or_path": "llm2vec-nf4", # 本地目录名
"peft_model_name_or_path": None,
"dtype": "bfloat16", "llm_dim": 4096, "device": "auto", "load_in_4bit": False,
},
},
# === 新增:FP16 编码器 ===
"llm2vec-fp16": {
"target": "kimodo.model.LLM2VecEncoder",
"kwargs": {
"base_model_name_or_path": "Aero-Ex/KIMODO-Meta3_llm2vec_FP16",
"peft_model_name_or_path": None,
"dtype": "float16", "llm_dim": 4096, "device": "auto", "load_in_4bit": False,
},
},
# === 新增:bitsandbytes 4bit 量化 ===
"llm2vec-bnb-4bit": {
"target": "kimodo.model.LLM2VecEncoder",
"kwargs": {
"base_model_name_or_path": "McGill-NLP/LLM2Vec-Meta-Llama-3-8B-Instruct-mntp",
"peft_model_name_or_path": "McGill-NLP/LLM2Vec-Meta-Llama-3-8B-Instruct-mntp-supervised",
"dtype": "bfloat16", "llm_dim": 4096, "device": "auto", "load_in_4bit": True,
},
},
}
关键点:
llm2vec-nf4预设中base_model_name_or_path的值是"llm2vec-nf4"(本地目录名),不是 HuggingFace repo ID。因为TEXT_ENCODERS_DIR环境变量会将此值拼接为完整路径。
改动 2:kimodo/model/llm2vec/llm2vec_wrapper.py
替换 __init__ 和 to 方法,支持 peft_model_name_or_path=None 和 load_in_4bit 参数:
import os
from typing import Optional # 新增 import
import numpy as np
import torch
from .llm2vec import LLM2Vec
class LLM2VecEncoder:
"""LLM2Vec text embeddings."""
def __init__(
self,
base_model_name_or_path: str,
peft_model_name_or_path: Optional[str] = None, # 改为 Optional
dtype: str = "bfloat16",
llm_dim: int = 4096,
device: str = "auto",
load_in_4bit: bool = False, # 新增参数
) -> None:
torch_dtype = getattr(torch, dtype)
self.llm_dim = llm_dim
cache_dir = os.environ.get("HUGGINGFACE_CACHE_DIR")
if "TEXT_ENCODERS_DIR" in os.environ:
base_model_name_or_path = os.path.join(
os.environ["TEXT_ENCODERS_DIR"], base_model_name_or_path)
if peft_model_name_or_path is not None:
peft_model_name_or_path = os.path.join(
os.environ["TEXT_ENCODERS_DIR"], peft_model_name_or_path)
load_kwargs = {"torch_dtype": torch_dtype, "cache_dir": cache_dir}
if load_in_4bit:
from transformers import BitsAndBytesConfig
load_kwargs["quantization_config"] = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch_dtype,
bnb_4bit_use_double_quant=True,
bnb_4bit_quant_type="nf4",
)
self.model = LLM2Vec.from_pretrained(
base_model_name_or_path=base_model_name_or_path,
peft_model_name_or_path=peft_model_name_or_path,
**load_kwargs,
)
env_device = os.environ.get("TEXT_ENCODER_DEVICE")
if env_device:
device = env_device
if device == "auto":
device = "cuda" if torch.cuda.is_available() else "cpu"
self._device = device
is_bnb_quantized = getattr(self.model.model, "is_loaded_in_4bit", False) or getattr(
self.model.model, "is_loaded_in_8bit", False)
if device is not None and not is_bnb_quantized:
self.model = self.model.to(device)
self.model.eval()
for p in self.model.parameters():
p.requires_grad = False
def to(self, device: torch.device):
is_bnb_quantized = getattr(self.model.model, "is_loaded_in_4bit", False) or getattr(
self.model.model, "is_loaded_in_8bit", False)
if not is_bnb_quantized:
self.model = self.model.to(device)
self._device = str(device) if not isinstance(device, str) else device
return self
改动要点:①
peft_model_name_or_path改为Optional[str];② 新增load_in_4bit参数;③ 检测 bnb 量化状态,量化模型不能调用.to();④TEXT_ENCODERS_DIR拼接时检查peft_model_name_or_path is not None。
六、关闭后处理(可选)
如果未编译 MotionCorrection C++ 扩展,需要关闭后处理默认设置。编辑 kimodo/demo/config.py:
# 原始值
INIT_POSTPROCESSING = True
# 改为
INIT_POSTPROCESSING = False
七、运行生成
方式 A:CLI 命令行生成
cd D:/kimodo
set CHECKPOINT_DIR=D:/kimodo/models
set TEXT_ENCODERS_DIR=D:/kimodo/models
set TEXT_ENCODER=llm2vec-nf4
set TEXT_ENCODER_MODE=local
set TEXT_ENCODER_DEVICE=cpu
set HF_ENDPOINT=https://hf-mirror.com
"D:/kimodo/env/Scripts/python.exe" -m kimodo.scripts.generate "A person walks forward." --model kimodo-soma-rp --duration 4 --diffusion_steps 50 --num_samples 1 --seed 42 --output D:/kimodo/test_output/walk_forward --bvh --no-postprocess
参数说明:
| 参数 | 说明 | 示例值 |
|---|---|---|
--model |
模型名称 | kimodo-soma-rp |
--duration |
动作时长(秒) | 4 |
--diffusion_steps |
扩散步数(越多质量越好,越慢) | 50 |
--num_samples |
生成数量 | 1 |
--seed |
随机种子 | 42 |
--output |
输出路径前缀 | D:/kimodo/test_output/walk_forward |
--bvh |
输出 BVH 格式 | – |
--no-postprocess |
跳过后处理 | – |
方式 B:Web UI 生成
创建一键启动脚本 start_kimodo_web.bat:
@echo off
cd /d "%~dp0"
set "CHECKPOINT_DIR=D:kimodomodels"
set "TEXT_ENCODERS_DIR=D:kimodomodels"
set "TEXT_ENCODER=llm2vec-nf4"
set "TEXT_ENCODER_MODE=local"
set "TEXT_ENCODER_DEVICE=cpu"
set "HF_ENDPOINT=https://hf-mirror.com"
set "SERVER_PORT=7860"
set "KIMODO_MODEL=kimodo-soma-rp"
echo Patching viser ...
"%~dp0envScriptspython.exe" "%~dp0patch_viser.py"
echo Starting Kimodo Web preview ...
echo Open in browser: http://localhost:%SERVER_PORT%
"%~dp0envScriptspython.exe" -m kimodo.demo --model %KIMODO_MODEL%
pause
双击运行后,浏览器打开 http://localhost:7860 即可使用 Web UI。
环境变量速查
| 变量 | 作用 | 本机值 |
|---|---|---|
CHECKPOINT_DIR |
模型根目录 | D:/kimodo/models |
TEXT_ENCODERS_DIR |
编码器根目录 | D:/kimodo/models |
TEXT_ENCODER |
编码器预设名 | llm2vec-nf4 |
TEXT_ENCODER_MODE |
编码器模式 | local |
TEXT_ENCODER_DEVICE |
编码器运行设备 | cpu(8GB 显卡用 cpu) |
HF_ENDPOINT |
HuggingFace 镜像 | https://hf-mirror.com |
八、Blender 集成
BVH 导入脚本
创建 blender_import_bvh.py,用于在 Blender 后台模式导入 BVH 并验证:
"""
Blender script: import BVH file and verify the motion data.
Usage: blender --background --python blender_import_bvh.py -- <bvh_file_path>
"""
import sys
import os
import bpy
def import_and_verify_bvh(bvh_path):
print(f"[Blender BVH Import] Starting import of: {bvh_path}")
if not os.path.exists(bvh_path):
print(f"[ERROR] BVH file not found: {bvh_path}")
return False
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
try:
bpy.ops.import_anim.bvh(filepath=bvh_path)
print("[Blender BVH Import] BVH imported successfully.")
except AttributeError:
try:
bpy.ops.import_bvh.bvh(filepath=bvh_path)
except Exception as e:
print(f"[ERROR] Failed to import BVH: {e}")
return False
except Exception as e:
print(f"[ERROR] Failed to import BVH: {e}")
return False
armatures = [obj for obj in bpy.context.scene.objects if obj.type == 'ARMATURE']
if not armatures:
print("[ERROR] No armature found after BVH import.")
return False
armature = armatures[0]
print(f"[Blender BVH Import] Armature name: {armature.name}")
print(f"[Blender BVH Import] Bone count: {len(armature.data.bones)}")
if armature.animation_data and armature.animation_data.action:
action = armature.animation_data.action
frame_count = int(action.frame_range[1] - action.frame_range[0] + 1)
print(f"[Blender BVH Import] Total frames: {frame_count}")
blend_path = bvh_path.replace('.bvh', '_imported.blend')
bpy.ops.wm.save_as_mainfile(filepath=blend_path)
print(f"[Blender BVH Import] Saved blend file: {blend_path}")
print("[Blender BVH Import] VERIFICATION PASSED.")
return True
if __name__ == "__main__":
argv = sys.argv
if "--" in argv:
argv = argv[argv.index("--") + 1:]
else:
argv = []
if len(argv) < 1:
sys.exit(1)
bvh_file = argv[0]
success = import_and_verify_bvh(bvh_file)
sys.exit(0 if success else 1)
命令行导入
"K:/Program Files/blender/blender.exe" --background --python "D:/kimodo/blender_import_bvh.py" -- "D:/kimodo/test_output/walk_forward.bvh"
注意:传给 Blender 的 BVH 路径必须用 Windows 风格(
D:/...或D:...),不能用 Git Bash 的/d/...格式。
在 Blender GUI 中手动导入
- 打开 Blender →
File→Import→Motion Capture (.bvh) - 选择生成的
.bvh文件 - 导入后可看到 78 骨骼的 SOMA 骨架和动画
九、自动化测试
端到端测试脚本
创建 auto_test.py,自动执行 Kimodo 生成 → BVH 导出 → Blender 导入的完整流程:
"""
Automated end-to-end test: Kimodo generate -> BVH export -> Blender import.
"""
import os
import subprocess
import sys
import time
KIMODO_DIR = "D:/kimodo"
PYTHON = "D:/kimodo/env/Scripts/python.exe"
BLENDER = "K:/Program Files/blender/blender.exe"
BLENDER_SCRIPT = "D:/kimodo/blender_import_bvh.py"
OUTPUT_DIR = "D:/kimodo/test_output"
TEST_PROMPTS = [
"A person walks forward.",
"A person does a squat.",
"A person jumps in place.",
]
def run_step(name, cmd, env=None, timeout=300):
print(f"n{'='*60}")
print(f"[STEP] {name}")
start = time.time()
result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout,
env={**os.environ, **(env or {})}, cwd=KIMODO_DIR)
elapsed = time.time() - start
if result.returncode == 0:
print(f"[PASS] {name} ({elapsed:.1f}s)")
return True
else:
print(f"[FAIL] {name} ({elapsed:.1f}s)")
return False
def check_file(path, min_size=100):
if not os.path.exists(path):
return False
size = os.path.getsize(path)
return size >= min_size
def main():
os.makedirs(OUTPUT_DIR, exist_ok=True)
all_passed = True
kimodo_env = {
"CHECKPOINT_DIR": "D:/kimodo/models",
"TEXT_ENCODERS_DIR": "D:/kimodo/models",
"TEXT_ENCODER": "llm2vec-nf4",
"TEXT_ENCODER_MODE": "local",
"TEXT_ENCODER_DEVICE": "cpu",
"HF_ENDPOINT": "https://hf-mirror.com",
}
for i, prompt in enumerate(TEST_PROMPTS):
test_name = f"test_{i+1}"
output_base = os.path.join(OUTPUT_DIR, test_name)
gen_cmd = [PYTHON, "-m", "kimodo.scripts.generate", prompt,
"--model", "kimodo-soma-rp", "--duration", "4",
"--diffusion_steps", "50", "--num_samples", "1",
"--seed", "42", "--output", output_base, "--bvh", "--no-postprocess"]
if not run_step(f"Kimodo generate: '{prompt}'", gen_cmd, kimodo_env, timeout=300):
all_passed = False
continue
bvh_path = output_base + ".bvh"
blend_cmd = [BLENDER, "--background", "--python", BLENDER_SCRIPT, "--", bvh_path]
if not run_step(f"Blender import: '{prompt}'", blend_cmd, timeout=120):
all_passed = False
continue
return 0 if all_passed else 1
if __name__ == "__main__":
sys.exit(main())
测试结果(2026-08-25 实测)
| 测试 | Prompt | 生成耗时 | BVH 大小 | 骨骼数 | 帧数 | Blender 导入 |
|---|---|---|---|---|---|---|
| 1 | “A person walks forward.” | 52.5s | 274KB | 78 | 120 | ✅ |
| 2 | “A person does a squat.” | 61.4s | 275KB | 78 | 120 | ✅ |
| 3 | “A person jumps in place.” | 42.6s | 274KB | 78 | 120 | ✅ |
全部 3/3 测试通过,总耗时 2 分 45 秒。
十、踩坑汇总
| # | 问题 | 原因 | 解决方案 |
|---|---|---|---|
| 1 | GitHub 直连超时 | 国内网络 | 用 ghfast.top 镜像 + --depth 1 |
| 2 | PyTorch 下载超时 | 包体 2.5GB | 重试,pip 支持断点续传 |
| 3 | MotionCorrection 编译失败 | 缺 MSVC + CMake | SKIP_MOTION_CORRECTION_IN_SETUP=1 |
| 4 | pip install -e ".[all]" 卡死 |
git 依赖从 GitHub 拉取 | 分步安装 |
| 5 | viser 依赖版本冲突 | SOMA-X 升级了依赖 | 重新安装 viser 要求的版本 |
| 6 | SOMA-X git 依赖卡死 | GitHub 连接不稳定 | 先 clone 到本地再安装 |
| 7 | HuggingFace 连接超时 | 国内网络 | HF_ENDPOINT=https://hf-mirror.com |
| 8 | huggingface_hub 下载被阻断 | safe-delete shim | 用 curl 直接下载 |
| 9 | “Model folder not found” | 目录名不匹配 | 目录名改为 Kimodo-SOMA-RP-v1.1 |
| 10 | viser Web UI 启动失败 | npm/npx POSIX 路径 | 运行 patch_viser.py |
| 11 | Blender BVH 导入报文件不存在 | Git Bash 路径格式 | 用 Windows 路径 |
十一、注意事项
- BVH 是 SOMA 骨架:Kimodo 输出的 BVH 使用 SOMA 骨架定义(78 骨骼),与 UE/Unity 的标准人形骨架不同。要在游戏引擎中使用,需要额外做 retarget(骨骼重定向)。
- 后处理未启用:本教程跳过了 MotionCorrection 编译。如需启用,需安装 Visual Studio 2022 + CMake。
- CPU 编码较慢:8GB 显卡用
TEXT_ENCODER_DEVICE=cpu时,每个动作生成约 40-60 秒。12GB+ 显卡可设为cuda。 - viser 补丁需重复运行:每次重装或升级 viser 后都需要重新运行
patch_viser.py。 - Python 版本锁定 3.11:不要升级到 3.12+,bitsandbytes 等依赖兼容性差。
- seed 影响结果:相同 seed + 相同 prompt 会生成相同动作。改变 seed 可获得不同变体。
十二、文件清单
| 文件 | 路径 | 用途 |
|---|---|---|
| Kimodo 仓库 | D:kimodo |
主程序代码 |
| Python 虚拟环境 | D:kimodoenv |
隔离运行环境 |
| Kimodo 模型 | D:kimodomodelsKimodo-SOMA-RP-v1.1 |
扩散模型权重 (1.1GB) |
| NF4 编码器 | D:kimodomodelsllm2vec-nf4 |
量化文本编码器 (4.4GB) |
| SOMA-X | D:SOMA-X |
骨架定义库 |
| viser 补丁 | D:kimodopatch_viser.py |
Windows npm 修复 |
| BVH 导入脚本 | D:kimodoblender_import_bvh.py |
Blender BVH 导入验证 |
| 自动化测试 | D:kimodoauto_test.py |
端到端测试脚本 |
| Web UI 启动器 | D:kimodostart_kimodo_web.bat |
一键启动 Web UI |
相关链接
- 原始教程:知乎文章
- Kimodo GitHub:https://github.com/nv-tlabs/kimodo
- Kimodo 模型:HuggingFace
- NF4 编码器:HuggingFace
- SOMA-X:GitHub
- HuggingFace 镜像:https://hf-mirror.com
- GitHub 镜像:https://ghfast.top