传统3D感知模型大多是在封闭类别集上训练的:数据集标注了20类或者200类物体,模型就只会识别这些类别,遇到没见过的东西就束手无策。而开放词汇3D理解(Open-Vocabulary 3D Understanding)的目标是让模型像人一样,理解任意自然语言描述并在3D场景中找到对应的部分。比如输入“带有台灯的桌子”或者“靠窗的位置”,模型能直接在点云中定位到相关的点集,甚至进一步支持编辑操作,比如删除某个物体、改变材质、移动位置。这项技术正在成为3D内容创作、机器人交互、数字孪生等领域的核心基础设施,值得每一位做3D方向的工程师认真了解。

开放词汇3D理解的核心原理:3D特征与语言空间对齐
要理解开放词汇3D理解,首先要明白它的核心思想:不是在3D空间里重新学一套语义分类器,而是把3D数据“翻译”到语言模型已经掌握的语义空间中。CLIP这类视觉语言预训练模型通过对数亿张图文对的学习,已经建立了一个非常丰富的自然语言语义空间,任何文本描述都可以编码成一个向量,并且语义相近的文本在向量空间中距离也近。开放词汇3D理解的关键,就是为点云中的每个点(或者每个局部区域)也学习一个同样维度的特征向量,使得这个向量能与描述该点语义的文本向量对齐。
具体到实现层面,主要有三条技术路线。第一种是2D到3D的特征蒸馏:先用2D开放词汇分割模型(如SAM、OpenSeg、MaskCLIP)对场景的多视角图像做像素级特征提取,再利用已知的相机位姿把这些2D特征反投影融合到3D点云上,代表工作有OpenScene和LERF。第二种是直接在3D数据上做对比学习,用3D编码器提取点云特征,与文本特征做对比损失训练,代表工作有OpenShape和ULIP。第三种是基于NeRF或3D高斯泼溅的隐式场方法,在辐射场中额外存储一个语言特征维度,查询任意空间位置时直接插值得到语义向量。三种路线各有取舍:2D蒸馏方式对几何精度要求高但语义来源丰富,3D原生方式推理更快,隐式场方式则天然支持连续空间查询。
无论哪条路线,最终的用户交互接口都是相似的:把用户的查询文本通过文本编码器得到一个查询向量,然后与场景中每个3D点的特征向量计算余弦相似度,相似度超过阈值的点就被认为命中了查询语义。这个过程完全不需要重新训练模型,换一个查询词立即生效,这就是“开放词汇”的含义所在。
代表性方案对比:OpenScene、LERF与3D高斯泼溅路线
OpenScene是2D蒸馏路线的经典工作。它的流程是先对场景的多个视角渲染图像,用2D开放词汇分割模型提取每张图的逐像素语言特征,然后根据深度图和相机位姿把像素特征融合到点云上,得到一个带语言特征的3D场景表示。它的优点是对任何新场景都能零样本工作,缺点是特征融合过程比较耗时,且依赖较高质量的位姿重建结果。
LERF(Language Embedded Radiance Fields)则选择在NeRF内部做文章。它在训练辐射场的同时,为每个空间位置额外回归一个语言特征向量,相当于把语义信息“烘焙”进了神经辐射场。这样做的好处是查询是连续的,任意一个3D坐标都能得到语义,而且体积渲染天然处理了遮挡关系,同一个位置不同语义的物体会按可见性加权。3D高斯泼溅(3D Gaussian Splatting)流行之后,社区很快出现了LangSplat、Gaussian Grouping等工作,把语言特征挂在每个高斯基元上,既保留了高斯泼溅的实时渲染速度,又支持开放词汇查询和编辑,目前是学术界和工业界都非常活跃的方向。
从工程选型角度看,如果你的场景已有成熟的重建管线(比如COLMAP或NeRF Studio),LERF和LangSplat类方案集成成本低;如果你拿到的是纯点云而没有原始图像,那么OpenShape这类3D原生方案或者OpenScene的预计算特征更适合;如果目标是交互式编辑而不仅仅是查询,高斯泼溅路线因为显式表示每个物体,删除、移动、重着色的操作实现起来最直接。
实战:搭建一个自然语言查询3D点云的最小可用系统
下面用Python演示一个最小可用的开放词汇点云查询系统。思路是加载预先蒸馏好的点云语言特征(很多公开数据集和模型仓库会直接提供),用CLIP文本编码器编码用户查询,计算相似度后可视化命中区域。为了让代码可以独立运行,这里用随机数据模拟点云特征,实际项目中替换为真实特征即可。
import numpy as np
import torch
from open_clip import create_model_and_transforms, get_tokenizer
# 加载CLIP模型和分词器
model, _, preprocess = create_model_and_transforms('ViT-B-32', pretrained='openai')
tokenizer = get_tokenizer('ViT-B-32')
model.eval()
def encode_text(query):
"""将自然语言查询编码为归一化文本向量"""
tokens = tokenizer([query])
with torch.no_grad():
text_feat = model.encode_text(tokens)
text_feat = text_feat / text_feat.norm(dim=-1, keepdim=True)
return text_feat.squeeze(0).numpy()
# 模拟一个点云及其语言特征(实际项目中来自2D蒸馏或3D编码器)
num_points = 50000
points = np.random.rand(num_points, 3).astype(np.float32) * 10
point_feats = np.random.randn(num_points, 512).astype(np.float32)
point_feats /= np.linalg.norm(point_feats, axis=1, keepdims=True)
def open_vocab_query(query, threshold=0.25):
"""开放词汇查询:返回命中查询语义的点索引"""
text_feat = encode_text(query) # (512,)
sims = point_feats @ text_feat # (num_points,)
mask = sims > threshold
return np.where(mask)[0], sims[mask]
indices, scores = open_vocab_query("a red chair")
print(f"命中点数: {len(indices)}, 最高相似度: {scores.max():.3f}")
这段代码里最关键的一行是point_feats @ text_feat,它把整个开放词汇查询压缩成了一次矩阵乘法,这也是这类系统能做到近实时响应的原因。真实场景中一个点云可能有数百万个点,512维特征的矩阵乘在GPU上毫秒级就能完成。阈值的选择需要根据场景调整,通常0.2到0.3之间比较稳妥,也可以用softmax把相似度转成概率图做更平滑的可视化。
从查询到编辑:自然语言驱动的3D场景修改
查询只是第一步,编辑才是开放词汇理解真正释放价值的地方。有了逐点的语义标签,编辑操作可以拆解为三个步骤:先用自然语言定位目标物体的点集,再把点集聚类成实例(通常用DBSCAN或者几何连通性分析),最后对整个实例施加变换。以删除物体为例,定位到的点直接从点云中移除即可;以移动物体为例,需要同时移动点集并修复留下的空洞,常用做法是用周围点的表面补洞算法填充。
from sklearn.cluster import DBSCAN
def segment_instance(query, eps=0.15, min_samples=50):
"""根据查询定位点集并聚类成实例"""
indices, _ = open_vocab_query(query)
if len(indices) == 0:
return None
cluster = DBSCAN(eps=eps, min_samples=min_samples)
labels = cluster.fit_predict(points[indices])
# 取最大的簇作为目标实例
largest = np.bincount(labels[labels >= 0]).argmax()
return indices[labels == largest]
def remove_object(query):
"""删除查询指定的物体"""
inst = segment_instance(query)
if inst is None:
print("未找到目标物体")
return points
keep = np.ones(len(points), dtype=bool)
keep[inst] = False
return points[keep]
new_points = remove_object("the wooden table")
print(f"删除后剩余点数: {len(new_points)}")
如果场景表示是3D高斯泼溅,编辑会更加优雅:每个高斯基元携带语言特征和实例编号,删除物体只需移除对应的高斯集合,改变颜色只需修改这些高斯的球谐系数,渲染管线完全不用动。Gaussian Grouping这类工作还支持把编辑后的场景重新渲染成新视角图像,等于实现了“用一句话P图”的3D版本,在影视预演和游戏资产迭代中已经有实际应用。
落地时的常见坑与优化建议
第一个常见的坑是细粒度查询的失效。CLIP这类模型对“红色椅子”这种属性加类别的组合理解尚可,但对空间关系(“桌子左边的椅子”)和计数类查询(“三把椅子中的第二把”)理解很弱。如果业务需要空间关系推理,需要在语言特征之上再叠加一层空间逻辑,比如先做实例分割,再用LLM根据实例的空间坐标做关系推理,形成“开放词汇定位加语言模型推理”的两阶段架构。
第二个坑是多视角特征融合的冲突。2D蒸馏路线中,不同视角对同一点可能给出矛盾的语义(遮挡、反光都会造成干扰),简单平均会模糊掉边界。实践中的改进包括按视角可靠性加权、取特征最大值激活等策略。第三个坑是性能问题:如果查询频率高,建议把点云特征预先量化存储,比如用FAISS建立特征索引,或者用PCA降到128维再计算相似度,能带来数倍的吞吐提升。
总体来看,开放词汇3D理解已经从论文阶段走向了工程可用阶段。对于想做智能3D编辑器、机器人语音交互或者空间检索系统的团队,建议从预训练模型加公开数据集起步,先跑通查询链路验证效果,再根据业务精度要求决定是否在自己的数据上做微调。自然语言作为人机交互的最高带宽接口,与3D场景的结合才刚刚开始,值得持续投入。