HumanML3D数据集构建实战:文本驱动3D人体动作生成 📅 发布时间:2026/9/18 9:10:12 👁 浏览次数: 1. HumanML3D 数据集到底解决什么问题1.1 从文字到动作这个数据集卡在什么位置做文本驱动的三维人体动作生成绕不开 HumanML3D。它本质上是一个文本—动作成对的标注数据集把一句人话比如一个人向前走两步然后转身挥手和一段精确到骨架关节旋转的三维动作序列绑在一起。训练一个模型能听懂文本、生成动作就必须有大量这种配对样本而 HumanML3D 是目前公开可获取、规模和质量都比较均衡的一个。它的核心价值在于把三件本来分散的东西拼到了一起原始动作来自 AMASS 和 KIT Motion-Language、统一的骨架表示、以及人工撰写并清洗过的文本描述。没有它你得自己找人给动作写描述或者自己把不同来源的 BVH、SMPL 参数对齐成同一套骨架这两件事都极其耗时。适合谁来用这个数据集呢做文本到动作生成方向的研究生、做数字人/虚拟角色驱动的工程同学、以及想复现相关论文的开发者。如果你只是想在 Demo 里让角色动起来其实用不上它但凡你要训练或微调一个 text-to-motion 模型这个数据集基本是起点。1.2 规模、来源与构成一览先把账算清楚免得下载到一半发现硬盘不够或者对不上论文里的数字。HumanML3D 官方给出的口径是约 14616 段动作序列对应约 44970 条文本描述平均每段动作配 3 条不同写法的描述。这个数量级在同类数据集里属于偏大的足够支撑一个中等规模模型的训练。它的动作来源主要有两块一块是 AMASS这是一个把大量动捕数据统一到 SMPL 身体模型参数空间的大集合HumanML3D 从中挑选了质量较好的子集另一块是 KIT Motion-Language 数据集本身带有人工标注的文本HumanML3D 对其做了重新的文本清洗和扩写。文本部分则是通过众包加人工校对的方式为每段动作写多条描述。这里有个容易被忽略的点HumanML3D 的下载从来不是下载一个压缩包那么简单它是下载原始数据 在本地跑脚本生成的流程。理解这一点后面所有步骤才顺理成章。1.3 为什么不直接提供一个压缩包很多人第一次找这个数据集时会困惑为什么 GitHub 仓库里没有直接的HumanML3D.zip。原因不复杂一是授权AMASS 和 KIT 都有自己的使用协议原始动作数据不能随便二次分发HumanML3D 作者只能提供构建脚本让你用自己申请到的原始数据在本地生成二是体量原始动捕数据、SMPL 模型、中间产物加起来远超普通网盘能承载的范围三是可复现性脚本化的构建流程能保证每个人拿到的东西是从同一份原始数据、同一套代码推出来的。这个设计带来一个直接后果构建过程对环境和路径相当敏感。我见过不少人是卡在路径写错、文件缺失、模型版本不对上而不是卡在算力。所以接下来我会把前置条件、目录结构和每一步的意图都讲透你可以照着抄。2. 下载之前必须先搞定的前置条件2.1 存储与算力预算盘点在动手之前先把磁盘和显存这两件事想清楚。原始 AMASS 全套解压完能到几十 GB你只需要其中 HumanML3D 用到的那部分但下载阶段往往还是会拿到不少冗余。生成后的特征文件本身只有几 GB.npy格式的运动向量和文本向量所以最终的 HumanML3D 目录并不夸张压力主要在中间过程。CPU 方面姿态处理脚本是单进程跑 numpy 计算速度取决于你的单核性能和原始文件数量跑一遍几个小时是常态。GPU 不是必须的但如果你要提取文本的 sentence embedding用 GPU 会快很多。显存 8GB 以上就够因为这个阶段不涉及大模型推理只是跑一个 distilbert 级别的编码器。我的建议是准备一块至少 100GB 空闲的固态盘把原始数据和处理产物分开放。机械盘也能用但脚本大量随机读取小文件时速度差距很明显。2.2 Python 环境与依赖版本环境是这类项目的隐形杀手。官方仓库的代码有一定年头依赖里对 numpy、torch、smplx 的版本比较敏感。我的做法是单独建一个 conda 环境不要和日常环境混。conda create -n humanml3d python3.8 -y conda activate humanml3d pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install numpy1.23.5 scipy pandas tqdm smplx0.1.28 spacy python -m spacy download en_core_web_sm版本上我踩过的坑是numpy 2.x 和这套老代码兼容性差很多地方会报np.float已移除之类的错smplx 的版本如果太新加载模型时的参数名会对不上。上面这套组合是我实测比较稳的。注意如果你用的是 Apple Siliconsmplx 和部分依赖可能编译不过建议直接在 x86 服务器或带独显的机器上构建省得折腾。2.3 需要提前申请的原始数据与模型这是整个流程里唯一非技术但最耗时的环节。HumanML3D 依赖两个需要注册申请的资源第一个是 AMASS。你要去它的官网注册账号然后逐个勾选你需要的子数据集并同意对应的许可条款。不同子集由不同机构维护条款不一样审核通常几个工作日内完成。申请通过后你会拿到下载链接按文件夹逐个下载。第二个是 SMPL 或 SMPLH 的身体模型文件。姿态处理脚本需要它来做正向运动学把参数还原成关节坐标。这个同样要注册申请下载下来是一堆.pkl文件。KIT Motion-Language 相对友好一些通常可以通过公开链接获取但你还是得确认一遍它的许可条款。我的经验是把这三个来源的申请一次性都提交了等待审核的时间并行处理不要串行等。3. 完整下载与本地构建实操3.1 仓库克隆与目录规划先把代码拉下来然后规划好一个干净的目录树。目录规划不是形式主义这套脚本里有大量相对路径和硬编码的文件夹名你按它的预期摆好后面能省掉大量改路径的功夫。git clone https://github.com/EricGuo5513/HumanML3D.git cd HumanML3D mkdir -p deps我建议的最终结构是这样HumanML3D/存放代码HumanML3D/deps/下面放amass/、kit/、smpl_models/和一个glove/生成出来的new_joints/、new_joint_vecs/、texts/、train.txt等直接放在仓库根目录。这个结构是脚本默认期望的照着摆最省事。克隆完成后先别急着跑花五分钟把raw_pose_processing.py、motion_representation.py、text_representation.py这三个主脚本从头读一遍尤其是它们开头几行的路径变量。你需要改动的通常就那几处。3.2 AMASS 与 KIT 原始数据的落位把申请到的 AMASS 数据解压后你会看到按子数据集名称分的一堆文件夹每个文件夹里是.npz格式的动作文件。KIT 的数据结构不太一样通常是.npy的动作加一份.txt的文本对照。关键点是不要把所有 AMASS 子集都塞进去HumanML3D 只用其中一部分。官方脚本里会维护一个清单文件类似amass_data_list的东西你把它列到的文件放进去就行。多放不会报错但会白白浪费处理时间少放则会直接漏数据。我第一次做的时候把整个 AMASS 都放进去结果跑了很久才发现有一半是没用的。SMPL 模型文件按脚本预期命名好通常是neutral/male/female三个模型加上对应的J_regressor和三脚趾的关节回归文件。命名对不上是新手最常见的报错来源之一。提示解压和搬运阶段建议用rsync而不是mv中途断了可以续也不会因为一次误操作把原始文件搞丢。3.3 姿态处理与运动特征生成真正进入构建环节分两步走。第一步是原始姿态处理把 AMASS 和 KIT 的原始参数统一到同一套骨架空间python raw_pose_processing.py这一步内部做的事是读取每个.npz里的 pose、trans、betas用 SMPL 做正向运动学得到关节位置把不同来源的坐标系对齐到统一朝向一般是让角色面朝固定方向并统一帧率。为什么必须做朝向归一化因为不同动捕数据集录制的朝向很随意如果不对齐模型会把朝向当成一个需要学习的变量白白浪费容量。第二步是运动表示生成python motion_representation.py这一步把处理好的关节位置和旋转转换成那个著名的 263 维向量。为什么是向量而不是原始旋转矩阵因为下游模型无论是 Transformer 还是扩散模型需要一个定长、连续、易插值的数值表示而原始的四元数或旋转矩阵存在表示冗余和插值问题。263 维这个设计后面会详细拆。跑的过程中会看到进度条每个动作大约几百毫秒到一秒。14616 个动作耐心点。中途断了不要慌这类脚本通常支持从中间产物继续但更稳妥的做法是先把已经生成好的.npy备份一份。3.4 文本特征提取与预训练编码器文本侧要单独跑python text_representation.py它会为每条文本描述生成两种特征一种是词级别的 embedding用 GloVe一种是句子级别的 embedding用 distilbert。为什么两种都要因为文本到动作的模型通常需要同时理解局部词序和整体语义词向量负责前者句向量负责后者拼接起来信息更全。这一步会自动下载预训练权重如果网络不通你需要提前手动下载好 distilbert 和 glove 文件按脚本预期的目录放进去。我遇到过的坑是 glove 的版本不对词表对不上导致大量词变成未知最后文本特征几乎全废。记得核对一下词表覆盖率。3.5 产物校验确认数据集真的可用跑完之后new_joint_vecs/里应该是 14616 个.npy每个形状是(帧数, 263)new_joints/里是对应的关节坐标texts/里是文本描述根目录下应该有train.txt、val.txt、test.txt三个划分文件。写一个十几行的校验脚本抽查几件事文件总数对不对、随机抽几个.npy检查是否存在 NaN 或全零、检查帧数分布是否异常比如有没有只有一帧的坏样本、检查文本文件和动作文件的文件名是否一一对应。这一步花不了几分钟但能帮你提前发现问题不至于训练到一半才发现数据是坏的。import numpy as np, os d new_joint_vecs files [f for f in os.listdir(d) if f.endswith(.npy)] print(total:, len(files)) bad [] for f in files[:200]: a np.load(os.path.join(d, f)) if np.isnan(a).any() or a.std() 1e-6: bad.append(f) print(suspicious:, bad)4. 数据结构与 263 维特征逐段拆解4.1 目录组织与文件命名理解目录组织能让你在写 DataLoader 时少走弯路。new_joint_vecs存的是模型真正吃的 263 维运动特征new_joints存的是可读的关节三维坐标主要用来做可视化和计算某些几何指标。文本侧texts/下每个动作对应一个文本文件里面是该动作的多条描述通常会做 token 化后存成.npy。划分文件train.txt等一行一个动作 ID不带扩展名你在 DataLoader 里按这个 ID 去三个目录里取对应文件即可。这种ID 索引多源的组织方式很常见好处是划分和数据解耦你可以自己造不同的划分做交叉验证。4.2 263 维向量逐段拆解263 这个数字不是随便定的拆开看逻辑很清楚段落维度含义根节点旋转与线速度4骨盆朝向角速度、水平方向速度、根高度关节相对位置6321 个关节相对根节点的 xyz关节旋转12621 个关节的 6D 旋转表示局部速度6622 个关节相对父节点的速度脚部接触4双脚的接触二值标志加起来正好 263。为什么用 6D 旋转而不是四元数6D 表示取旋转矩阵前两列是连续的神经网络学起来更稳避免了四元数的双覆盖问题。为什么要有脚部接触标志因为动作生成里最常见的失真就是脚打滑显式给出接触信号能让模型学会该踩住的时候别动。4.3 文本标注与数据划分文本部分每个动作有 1 到 3 条以上的描述写法各异有的偏动作分解有的偏场景描述。模型训练时通常随机挑一条或者把多条都当作正样本。这个设计是为了让模型对同一动作有多个语言视角提升泛化。划分上Train/Val/Test 是官方给定的不要自己随机打乱重分否则和论文里的指标没法比。如果你想做自己的实验可以在官方划分基础上再切但报结果时要说清楚。5. 常见问题与排查技巧实录5.1 数据准备阶段的典型坑最常见的是文件缺失导致的 KeyError。脚本读取某个 AMASS 子集时找不到对应文件会直接崩。排查方法是把脚本报错的文件名记下来去原始数据里确认它到底在不在很多时候是解压不完整或者子集没申请。第二个坑是 SMPL 模型的关节回归矩阵版本不对导致生成的关节坐标整体偏移。判断方法是可视化一段动作看骨架是否合理。如果整体短了一截或者关节位置错乱八成是回归矩阵的问题。5.2 脚本运行阶段的报错numpy 版本冲突是最烦的一类报错信息通常长这样AttributeError: module numpy has no attribute float。解决办法就是降级别想着改代码改代码会引入更多未知问题。torch 的 CUDA 版本不匹配也会在文本特征提取时报错确认一下torch.cuda.is_available()。内存溢出一般发生在处理长动作序列时脚本一次性把整段加载进内存。如果你的机器内存小于 16GB考虑分批处理或者升级配置。5.3 排错速查表现象大概率原因处理方式找不到 npz 文件AMASS 子集缺失或路径错核对清单文件与目录关节位置错乱SMPL 回归矩阵不对换用官方推荐的 pklNaN 在特征里原始动作有坏帧剔除该样本文本全 UNKGloVe 词表不匹配换对应版本权重处理极慢单进程 机械盘换固态、考虑并行6. 拿到数据之后怎么用起来6.1 数据加载与批处理写完校验没问题就可以接 DataLoader 了。由于每条动作帧数不同常见做法是设定一个最大帧长比如 196 帧短的补零、长的裁剪并记录实际长度用于 mask。文本侧同样要统一长度。不要小看 mask 这一步很多生成质量差的问题根源就在 padding 没有正确屏蔽。def collate(batch): max_len max(x[motion].shape[0] for x in batch) ...6.2 评测指标要点HumanML3D 自带的评测脚本会算 FID、R-Precision、Diversity、MultiModality 等指标。跑评测时注意FID 依赖一个预训练的动作编码器这个编码器也要单独下载。R-Precision 衡量的是给一段生成动作能不能在候选文本里找到正确的那条是文本对齐质量的核心指标。我在复现别人的结果时发现同一个模型换不同的随机种子R-Precision 波动能有几个点所以别拿单次结果下结论多跑几次取平均再说。这一步偷懒后面写论文或者汇报时会被追问得很惨。