Token导航 LogoToken导航

KaiNinja实现3D生成模型部件拆分能力

更新时间 2026-10-15来源 科技行者正文 8618字阅读约 27分钟

2026年9月,一个叫KaiNinja的研究项目上线了。它做的事情听起来简单:给一张图片,生成一个3D模型。但这句话背后藏着一个行业已经卡了好几年的难题。

你可能没意识到,现在最好的3D生成模型,生成出来的东西全是"一整块"。

你上传一张椅子的照片,它给你一把椅子,但这把椅子是一整坨网格数据,椅背、椅腿、坐垫全部粘在一起,没有边界,没有接缝。你想把椅子腿单独拿出来改个颜色?不行。你想让椅背可以旋转做成一个动画?不行。你想把这把椅子的靠背换到另一把椅子上?也不行。

因为对模型来说,这从来就不是"一把椅子由几个零件组成",而是"一整块椅子形状的表面"。

3D生成模型不会拆零件,这事有多麻烦

先说说为什么这事重要。

游戏公司要做角色动画,得先把角色拆成头、躯干、四肢,然后给每个部位装骨骼。电影特效要做爆炸场景,得先知道桌子是由桌面和四条腿组成的,不然没法算物理碰撞。哪怕只是想给一件家具换个材质,你也得先分清楚哪部分是木头哪部分是金属。

*Native 3D生成器:直接从图片"去噪"生成3D模型的技术路线,不需要先生成多张视角图片再重建,速度快、质量高,是目前效果最好的3D生成范式。TRELLIS、TRELLIS.2、Hunyuan3D都属于这一类。

这些模型确实做得越来越好,材质、纹理、光照全都能生成得很逼真。但它们全都有一个共同的毛病:吐出来的是一坨融合在一起的网格,没有零件概念。

行业里现在有两条路子想解决这个问题。第一条路是"先生成后切割":让生成器出一个完整模型,再找个分割网络把它切成几块。这就像你先把一个蛋糕烤好,再拿刀切成几份。问题是,蛋糕烤的时候各种夹心已经混在一起了,你这一刀切下去,很可能把巧克力夹心和草莓夹心切得乱七八糟,因为烘烤过程根本没考虑过"这里要留出一条切割线"。

论文里提到一个具体数字:这种"先生成后切割"的方案,做一个模型的时间比另一条路线慢一个数量级,也就是十倍以上的时间开销。而且分割准不准,直接决定了最后零件切得好不好,模型自己没法纠正分割器的错误。

第二条路是"生成时就想好零件",比如让模型先框出几个零件的位置(用方框标注),再往每个框里填内容。这条路快是快了,但天生有个上限:你得先知道要生成几个零件、每个零件大概在哪,这本身就需要一次预测或分割,一旦这个预测错了,生成出来的零件要么叠在一起,要么根本对不上。

问题的根子:一个格子只能装一层"皮"

KaiNinja团队没有从"怎么切割"这个角度想问题,他们往更底层挖了一层,发现真正的瓶颈出在3D模型的存储方式上。

TRELLIS.2用的表示方法叫O-Voxel。

*O-Voxel:一种稀疏体素结构,把3D空间切成很多小格子,只在有表面的格子里存东西,每个格子存一个"对偶顶点",通过一种叫对偶轮廓化(dual contouring)的算法把这些顶点连起来变成网格表面。它的好处是能表示开放、非流形(比如薄片状)的复杂表面,还能带材质和贴图。

这套东西设计得很聪明,唯独有一个硬伤:一个格子只能存一层表面。

想象两个零件紧贴在一起,比如桌面和桌腿连接的地方。这两个零件的表面几乎贴在一起,中间几乎没有空隙。当你把这个区域切成格子的时候,这两层几乎重合的表面会落进同一批格子里。而O-Voxel的规则是每个格子只保留一个"代表性顶点",用一种叫二次误差函数的算法在两层表面之间拟合一个折中位置。

结果就是两层表面直接被拟合成了一层。

这不是分辨率不够的问题,你把格子切得再细,只要两个零件贴得足够近,这个问题永远存在。这是一个容量上的死结:这个存储格式从设计之初就没打算让两片表面共存在同一个格子里。

如果你家里有两片刚好能严丝合缝拼在一起的拼图,你把它们叠在一起放进一个只能装一张纸厚度的信封里,无论你把信封做得多精致,那两片拼图最终都会被压成一张纸的厚度,你没法从信封外面分辨出这原本是两片。这不是信封质量的问题,是信封这个容器的设计前提就不支持"两层紧贴的东西各自保留"。

这就是KaiNinja团队面对的核心矛盾:零件接触的地方,恰恰是分割任务最需要保留精确边界信息的地方,但现有的表示方式在这个地方会主动把信息抹掉。

解法:把一个格子拆成两套

既然一个体积装不下两层贴合的表面,那就用两个体积。

这个思路不是KaiNinja首创的,他们借鉴了一篇叫PartPacker的工作里的"双体积打包"(dual-volume packing)想法,但把它从原来那种基于SDF场的表示方式,搬到了TRELLIS.2用的O-Voxel网格上。

具体做法是这样:把一个物体的所有零件看成一张图里的节点,两个零件如果碰在一起,就在图上连一条边,这张图叫接触图。

*接触图:描述物体各零件之间物理接触关系的图结构,节点是零件,边代表两个零件有实际接触。KaiNinja判断"接触"的标准很严格:只要有一个体素格子同时被两个零件的表面占据,就算接触,还会按共享格子的数量给这条边加权重。

接下来对这张图做一次二染色,也就是把所有节点分成两组颜色,规则是相邻的节点(也就是互相接触的零件)不能是同一个颜色。染色完之后,把颜色A的零件全塞进一个体积(Volume A),颜色B的全塞进另一个体积(Volume B)。这样一来,同一个体积里的零件,天生就不会互相接触,那个"两层表面挤进一个格子"的问题就自然消失了。

论文里举了个例子挺形象的。一辆卡车,车身是一个整体,和轮子、窗户、后视镜都有接触,这是一个"星形"的接触图,车身作为中心节点和周围所有节点相连。二染色之后,车身自己占了Volume A(1个零件),轮子、窗户、镜子全塞进Volume B(11个零件)。一台微波炉稍微复杂点,最后拆成2+5的两组,中间有6条接触边。

这里有个技术上绕不过去的坎:不是所有的接触图都能被完美二染色。只有二部图才能被干净地分成两组互不相邻的颜色,现实里零件互相咬合、缠绕得复杂的物体,接触图往往不是二部图,会出现奇数环(比如三个零件互相都接触,形成一个三角形关系),这时候硬要二染色是染不出来的。

KaiNinja的解决办法是贪心地"合并":只要图里还有奇数环,就找环上权重最大的那条边(也就是接触最紧密的那两个零件),把它们合并成一个节点,重复这个过程直到图变成二部图为止。这意味着,接触特别复杂、零件互相嵌套得特别深的物体,最后会被迫把几个本该独立的零件捏成一个大零件。这是这套方案的代价,论文自己也坦诚承认了这一点,还专门在附录里证明了为什么这个限制没法通过增加体积数量彻底解决(三维空间中任意多个区域都可能两两相邻,所以理论上不存在一个固定数量的体积能兜住所有情况)。

让预训练模型学会"两套流"而不是推倒重来

光有了两个体积还不够,KaiNinja还得让生成模型知道怎么往这两个体积里填东西。

TRELLIS.2的生成过程分两个阶段,第一阶段决定"哪里有表面"(叫layout flow,布局流),第二阶段决定"这个表面具体长什么样"(叫refinement flow,精修流)。

*Rectified Flow(矫正流):一种类似扩散模型的生成技术,通过逐步"去噪"把一个随机噪声变成目标数据,TRELLIS.2和KaiNinja都用这套框架来生成3D内容。

KaiNinja的做法是把这两个阶段分开对待,因为它们各自面对的任务不一样。

第一阶段负责决定零件怎么分布、哪个零件归哪个体积,这是一个需要"全局协调"的联合决策,所以KaiNinja给这个阶段配了两套独立的权重(一套负责A体积,一套负责B体积),每隔几层网络再插入一个"跨体积注意力"模块,让两条流互相看一眼对方在干嘛。这个跨体积模块是零初始化的,也就是说训练刚开始的时候,这个模块完全不起作用,两条流各自为政,等训练进行下去,这个模块才慢慢学会怎么协调两边。

第二阶段的任务相对局部,就是把已经确定好位置的表面精修出细节,这个任务和原来TRELLIS.2预训练时做的事情几乎一样,所以KaiNinja压根没动这部分的权重,只是通过"注意力范围"的调整让两个体积各自精修:30层网络里有20层只让每个体积看自己的内容,剩下10层允许跨体积看一眼。

这种"分阶段区别对待"的设计思路,很像装修一栋老房子的时候,你不会把承重墙全部推倒重建。承重结构(也就是原模型已经学得很好的图像理解和局部几何精修能力)原样保留,你只在需要重新布局的地方(决定零件怎么分配)动手术,而且这个手术是先各自练熟,再慢慢学会配合,不是一上来就把两拨施工队混在一起干活。如果一开始就让两条流混在一起从零训练,那些还没学会怎么密切配合的模块产生的乱七八糟的梯度,会直接冲进已经训练得很好的预训练权重里,把原本学到的图像理解能力搅乱。

训练的三步走:先适应,再合并,最后一起磨合

这套两阶段设计带来了一个新问题:怎么把预训练好的单体积模型,变成能处理双体积的模型,同时还不破坏它原本学到的东西?

KaiNinja团队总结出预训练模型和目标任务之间存在三道鸿沟。第一道鸿沟是分布差异:预训练模型看过的都是完整物体,从没见过"半个物体、接触面暴露在外"的样子。第二道鸿沟是接口缺失:原模型压根不知道零件接触面长什么样。第三道鸿沟是协作缺失:两个体积的内容需要互相配合,但两条独立训练的流没有天然的默契。

针对第一阶段(布局流),KaiNinja设计了一套四步走的训练流程。

第一步叫"各自适应",把预训练好的单流模型复制两份,一份只在A体积的数据上微调,一份只在B体积的数据上微调,先让每一份权重适应"半个物体"这种新的数据分布,暂时不涉及两个体积怎么协作的问题。

第二步叫"无损合并",把两份微调好的权重原样装进两条流里,因为两份权重涉及的模块(比如注意力层、时间步调制)是各自独立的,所以这一步不需要做任何重新解释,合并完的模型行为上和两个独立的微调模型完全一样。

第三步是"冻结预热",先把刚才合并进来的两条流权重全部冻结,只训练那个负责跨体积协调的注意力模块,让这个新模块先学会怎么在不破坏已有能力的前提下建立联系。

第四步才是"联合微调",解冻所有参数,一起训练。

这个顺序不是随便安排的,如果跳过第三步直接联合训练,那个还没学会协调的新模块会把杂乱的梯度传给已经适应好的两条流,把它们训练成果搅乱;如果跳过第一步直接合并训练,等于让一套从没见过"半个物体"的权重同时去学两种它都不熟悉的新分布,训练难度陡增。

这个过程让我想起学一门新乐器合奏。如果你想让两个原本各自练熟了独奏的乐手临时组一个二重奏,比较靠谱的做法是先各自把自己的谱子练熟(对应第一步"各自适应"),然后让他们坐到一起但先不急着合奏,各自弹各自的先听一遍(对应第二步的"无损合并"),再专门抽时间只练习"怎么在对方弹奏的时候接进来"这个配合环节(对应第三步的"冻结预热"),最后才是完整的合奏排练(第四步"联合微调")。如果一上来就让两人合奏,两边都在适应新曲子又要适应对方,效果往往比按顺序来的差。

联合微调阶段还加了一个"互斥惩罚项"(disjointness penalty)。这个设计针对的问题是:训练过程没有天然的机制阻止两条流把同一块表面同时塞进A和B两个体积里,模型完全可能偷懒,让两个体积都生成差不多的东西。KaiNinja在每一步训练里,把两条流预测出的"占据情况"解码出来,如果两个体积在同一个位置都判断"这里有表面",就给这个重叠区域一个惩罚。论文里的实验显示,这个惩罚项让两个体积的重叠中位数从0.229降到0.184,明显减轻了"两边生成同一坨东西"的偷懒现象,虽然没能彻底根治。

第二阶段(精修流)反而不需要这么复杂的流程,因为它的骨干网络完全没变,只是注意力范围做了区隔,所以只用了"冻结预热+全量微调"两步,量级也小得多。

用AI agent写代码生成的数据,第一次拿来训练3D生成模型

模型架构讲完了,还有一个容易被忽略但其实很关键的部分:训练数据从哪来。

KaiNinja团队把四个数据集攒成一个语料库,一共19132个物体:articraft(8968个)、partnext(6358个)、trellis(1931个)、fusion360(1875个)。

其中最特别的是articraft这个数据集,它不是人工建模的,也不是传统扫描来的,而是一个LLM驱动的代码生成agent做出来的。

*Articraft:一套让大语言模型作为"编程agent"来生成带零件结构和物理关节的3D资产的系统。这个agent会写程序,用基础几何形状(比如立方体、圆柱体)拼出每个零件,再用物理关节把零件连接起来。因为零件是agent一步步用代码搭出来的,所以零件的划分方式是"写代码时天然确定"的,不存在人工标注可能带来的模糊和错误。

这一点其实挺有意思的。以前训练3D分割或者生成模型,零件标签往往来自人工标注,标注这件事本身就带有主观判断,两个人标同一个模型,划分边界可能都不完全一样。而agent生成的数据,零件边界是程序逻辑决定的,没有"标注噪声"这个说法。论文特别强调,这是第一次有研究用agent生成的3D资产去训练一个3D生成模型。

除了数据来源多样化,KaiNinja团队还做了两轮质量筛选。第一轮在体素化之前,保留零件数在2到32之间的物体,剔除零件之间严重穿插碰撞的(用碰撞深度和广义环绕数衡量重叠程度),去掉那些被背景平面或地面板主导的资产。第二轮在打包完成之后,要求每个物体都有合法的潜变量表示和渲染出来的条件图,还专门加了一个"平衡过滤器",确保A、B两个体积的体素数量和占据率不要差得太离谱,避免出现一个体积几乎是空的这种退化情况。

值得一提的是,因为O-Voxel本身就不要求表面是水密的(也就是完全封闭的),所以KaiNinja这套流程完全跳过了PartPacker基于SDF那套方案里必须做的"水密修复"和"外壳膨胀"步骤,原始的开放表面和材质信息都能保留下来。

结果怎么样:不仅拆得好,整体质量还变高了

说了这么多设计,最后还是要看实际效果。

KaiNinja拿五种代表性方法做对比:X-Part(先生成整体再分割重建)配了两个不同的生成器(TRELLIS.2和Hunyuan3D-2.1),OmniPart(先用2D图像分割再生成布局框),AutoPartGen(一个零件一个零件地自回归生成),还有PartPacker(同样用双体积打包思路但架构不同)。

在held-out测试集(986个五种方法都能跑通的物体)上,KaiNinja在全部七项指标上都是第一名。

跟表现最好的对照组Hunyuan3D-2.1+X-Part相比,KaiNinja在严格阈值下的整体F1分数(F10.05W)高了0.10,零件F1分数(F10.05P)高了0.09,整体的Chamfer距离(衡量几何形状差异的指标,越低越好)降低了40%。

*Chamfer距离:一种衡量两个点云或形状之间几何相似程度的指标,数值越小说明预测的形状和真实形状越接近。

F-score:这里用来衡量预测的表面点和真实表面点在某个距离阈值内匹配的比例,阈值越严格(比如0.05比0.1严格),越能反映模型在细节和边界处的精确度。

有个现象挺让人意外的:宽松阈值下大家差距不大,严格阈值下KaiNinja的优势明显放大,这说明差距主要来自精细几何和边界的把控,而不是大致轮廓对不对。

速度上,KaiNinja在一块H100显卡上生成一个带零件划分的物体大约需要24秒。作为对照,那个"先生成后分割"的X-Part级联方案,仅仅是导出一个69.2万顶点的网格文件就要花51.2秒,生成本身反而只要11.1秒,整个流程比KaiNinja慢了一个数量级。AutoPartGen因为要一个零件接一个零件地生成,花费的时间是KaiNinja的三倍左右。

最出乎意料的结果出现在整体(不分零件)质量的对比上。研究团队专门拿同一个TRELLIS.2骨干网络,用同样的训练数据做了微调,作为参照组,结果这个微调后的整体生成模型,严格F1分数是0.830。而KaiNinja,同样从这个骨干网络出发、同样看过这批数据,最后整体质量的F1分数达到了0.919,比微调版本高出0.089,失败率(Chamfer距离超过0.1视为失败)也从1.8%降到了0.7%。

这个结果反过来说明了一件事:双体积打包不只是一个方便切零件的容器,它本身似乎是一种更适合表达这批物体的表示方式。

研究团队还专门测试了模型在训练数据之外的泛化能力。他们从Sketchfab和GitHub上找了一批模型(这些来源没有出现在训练数据里),KaiNinja依然领先,整体F1分数比第二名高0.075。在一个完全外部的基准测试集HY3D-Bench上,整体几何质量KaiNinja依然是第一,但零件匹配的指标上,反而被Hunyuan3D-2.1+X-Part超过了。

研究团队对这个反转给出的解释挺坦诚的:HY3D-Bench标注零件的粒度比KaiNinja训练数据用的粒度要粗,KaiNinja习惯在接触面处就切开,结果一把椅子被它拆出的零件数比基准标注的还多,用Hungarian匹配算法打分的时候,多出来的零件都会被算成错误。而先生成整体再交给专门分割器的方案,分割粒度更容易调整去贴合某个具体基准的标注习惯。

这提醒了我一件事:一个模型在某个指标上"输了",未必是模型本身的问题,很可能是评价标准和模型的行为逻辑不在一个频道上。

还有哪些坑没填平

论文里专门用一整节坦承了局限性,这点我觉得挺难得的。

最根本的限制来自二染色这个数学约束本身:一旦物体的零件接触关系复杂到形成"密集缠绕"的结构,就必须合并零件才能凑出一个二部图,这时候的零件划分粒度会变粗。论文附录里甚至给出了数学论证:三维空间里任意数量的区域理论上都可能两两相邻,所以不存在任何固定数量的体积可以完全避免这个问题。

生成过程本身还有三种典型的失败模式。第一种是"欠分割",模型把物体的绝大部分都塞进一个体积,另一个体积只分到几个小零件,结果本该独立的几个零件因为挤在同一个体积里而被粘连成一块。第二种是"单体积坍缩",某个体积干脆什么都没生成,物体看起来整体没问题,但压根没被拆开,这种情况在1000个测试物体里出现了9次。第三种是"重复体积",两条流各自都生成了几乎一样的完整物体,装配出来的结果里有两份几乎重合的几何,被零件指标误判成很多碎小零件。

论文对这几个失败模式的解释挺诚实:预训练权重本来就是在"完整未分割物体"上学出来的,没有任何机制天然要求它输出一个"均衡的划分",也没有机制主动阻止两条流生成同一块表面。互斥惩罚项能缓解这个问题,但没法根治。

如果从一开始就用打包好的双体积数据从零训练模型,这个问题理论上能测试得更彻底,但研究团队直言这需要的算力和数据量超出了这次工作的范围。

写在后面

读完这篇论文,最让我意外的不是双体积打包这个设计本身,PartPacker之前已经提出过类似思路。真正让我多想了一层的是那个"整体质量反而变好了"的结果。

一般直觉里,给一个模型增加约束(这里是"零件不能相互接触"这个额外要求),应该是在拿生成自由度换取结构性,代价应该是整体质量打折扣。但KaiNinja的实验数据反过来了:加了约束之后,整体几何反而更准了。

这让我想到一个可能的解释,虽然论文没有直接下这个结论:也许"一坨完整物体"对模型来说其实是个更难学的目标,因为它把所有几何细节挤在一个连续的表面描述里,边界模糊、层次不清;而拆成两个各自内部无接触的体积,反而让模型能更干净地表达每一部分的形状,这种"分而治之"式的表示对生成任务本身也是一种简化。

如果这个猜测站得住脚,那可能意味着不少3D生成任务里,"表示方式选得对不对"这件事,比"网络架构设计得多精巧"更能决定上限。这和很多深度学习领域的经验其实是一致的,但每次看到具体的实验数字印证这一点,还是会觉得有点意思。

论文里那个"三种失败模式"的坦白也值得琢磨。一个模型在没有明确监督信号要求"均衡拆分"的情况下,会本能地倾向于走捷径,把大部分东西塞进一个体积,或者干脆两边生成同一份内容。这种"懒惰"行为其实在很多多分支、多头结构的模型里都会出现,怎么设计激励机制让不同分支真正各司其职,可能是个比看起来更普遍的问题。

如果一个物体的所有零件都紧紧咬合在一起,没有任何一种拆分方式能让它们互不接触,那这个物体到底应不应该被拆开?

Q&A

Q1:KaiNinja是什么?

A:KaiNinja是一个基于TRELLIS.2扩展的3D生成模型,可以直接从一张图片生成带零件划分的3D模型,每个零件都是独立可编辑的网格,不需要额外的分割网络。

Q2:KaiNinja相比传统"先生成后分割"的方案有什么优势?

A:KaiNinja速度更快,生成一个物体只需约24秒,比先生成整体再用分割网络切割的方案快一个数量级,同时在整体形状精度和零件划分准确度上都表现更好。

Q3:KaiNinja的训练数据有什么特别之处?

A:训练数据中包含了由LLM驱动的编程agent自动生成的3D资产(Articraft数据集),零件划分由生成程序的逻辑天然确定,不存在人工标注可能带来的误差和模糊性,这是该类数据首次被用于训练3D生成模型。

文章标签学术研究
资讯来源:由AI资讯编辑整理自互联网公开内容,版权归原作者所有,未经许可,不得转载。

继续浏览更多资讯

返回资讯目录

相关资讯

更多