Vision-Language-Action:LMDrive视觉编码器与 Q-Former
LMDrive 核心算法组件视觉编码器与 Q-Former1. 视觉编码器 (Memfuser)1.1 算法原理视觉编码器采用Transformer Encoder-Decoder 架构融合多视角图像与 LiDAR 点云数据输出紧凑的视觉特征表示。核心设计思想将多模态传感器数据统一映射到同一特征空间通过 Transformer 注意力机制实现跨模态信息交互输出可直接用于下游决策任务的结构化特征1.2 核心组件组件作用算法细节ResNet Backbone图像特征提取resnet50d/resnet26d输出多层特征图HybridEmbed特征向量化将 2D 特征图展平为 token 序列1x1 Conv 投影到 embed_dimPositionEmbeddingSine位置编码正弦位置编码支持相对位置信息View Embedding视角区分可学习向量区分前/左/右/后/中 5 个视角PointPillarLiDAR 处理将点云转换为伪图像再经 CNN 提取特征Transformer Encoder多模态融合6 层编码器融合所有视角特征Transformer Decoder特征解码6 层解码器生成轨迹点和交通预测1.3 前向传播流程defforward_features(self,front,left,right,rear,center,lidar,num_points):# 阶段1: 图像特征提取front_token,front_globalself.rgb_patch_embed(front)# [B, 768, H, W]left_token,left_globalself.rgb_patch_embed(left)# [B, 768, H, W]right_token,right_globalself.rgb_patch_embed(right)# [B, 768, H, W]rear_token,rear_globalself.rgb_patch_embed(rear)# [B, 768, H, W]center_token,center_globalself.rgb_patch_embed(center)# [B, 768, H, W]# 阶段2: LiDAR 特征提取 (PointPillar)lidar_tokenself.lidar_backbone(lidar,num_points)# [B, 768, 50, 50]# 阶段3: 添加视角嵌入features[front_token,left_token,right_token,rear_token,center_token]features[fself.view_embed[:,:,i:i1]fori,finenumerate(features)]# 阶段4: 添加位置编码foriinrange(len(features)):features[i]features[i]self.position_encoding(features[i])# 阶段5: 拼接全局特征global_featurestorch.cat([front_global,left_global,right_global,rear_global,center_global],dim1)# [B, 5, 768]returnfeatures,global_features,lidar_token1.4 特征融合机制defforward(self,x):# 1. 提取多模态特征features,global_features,lidar_tokenself.forward_features(...)# 2. 展平并拼接所有特征flattened[f.flatten(2).transpose(1,2)forfinfeatures]# [B, N, 768]encoder_inputtorch.cat(flattened[global_features,lidar_token],dim1)# 3. Transformer Encoder 编码memoryself.encoder(encoder_input)# [B, total_tokens, 768]# 4. Transformer Decoder 解码querytorch.cat([lidar_token,self.query_embed],dim1)hsself.decoder(query,memory)# 5. 输出预测waypointsself.waypoints_generator(hs)trafficself.traffic_pred_head(hs)returnhs,waypoints,traffic1.5 输入输出示例输入# 5个视角图像front_imagetorch.randn(1,3,224,224)# 前视主摄像头left_imagetorch.randn(1,3,112,112)# 左视摄像头right_imagetorch.randn(1,3,112,112)# 右视摄像头rear_imagetorch.randn(1,3,112,112)# 后视摄像头center_imagetorch.randn(1,3,112,112)# 前视中心摄像头# LiDAR 点云lidartorch.randn(1,9,40000)# 每个点包含 x,y,z,intensity,ring 等num_pointstorch.tensor([40000])输出# 融合后的视觉特征 (用于 Q-Former)feature_outputtorch.randn(1,65,768)# 65个token每个768维# 轨迹预测waypointstorch.randn(1,3,5)# 3个轨迹点每个包含 x,y,z# 交通参与者预测traffictorch.randn(1,8)# 8类交通对象概率2. Q-Former 特征转换器2.1 算法原理Q-Former 是一个可学习的视觉特征提取器通过一组 learnable query tokens 和交叉注意力机制从视觉编码器输出的特征中提取紧凑的语义特征。核心设计思想冻结视觉编码器利用预训练视觉模型的强大表征能力避免灾难性遗忘Learnable Query Tokens通过可学习的查询向量主动查询视觉特征交替注意力机制自注意力整合查询间信息交叉注意力从视觉特征中提取信息轻量级适配仅更新 Q-Former 参数高效适配下游任务2.2 核心组件组件作用算法细节Learnable Query Tokens特征查询向量随机初始化可学习更新默认 4 个BertEmbeddings嵌入层词嵌入 位置嵌入支持 query_embeds 拼接BertLayer注意力层自注意力 可选交叉注意力 FFNBertEncoder编码器堆叠12 层 BertLayer每 2 层插入交叉注意力BertLMHead语言建模头用于预训练阶段的掩码语言建模2.3 注意力机制设计交替注意力策略cross_attention_freq2Layer 0: 自注意力 → FFN Layer 1: 自注意力 → FFN Layer 2: 自注意力 → 交叉注意力 → FFN ← 提取视觉信息 Layer 3: 自注意力 → FFN Layer 4: 自注意力 → FFN Layer 5: 自注意力 → 交叉注意力 → FFN ← 提取视觉信息 ...交叉注意力实现BertSelfAttentionclassBertSelfAttention(nn.Module):def__init__(self,config,is_cross_attention):self.querynn.Linear(config.hidden_size,self.all_head_size)ifis_cross_attention:self.keynn.Linear(config.encoder_width,self.all_head_size)# 视觉特征维度self.valuenn.Linear(config.encoder_width,self.all_head_size)else:self.keynn.Linear(config.hidden_size,self.all_head_size)self.valuenn.Linear(config.hidden_size,self.all_head_size)defforward(self,hidden_states,encoder_hidden_statesNone):query_layerself.transpose_for_scores(self.query(hidden_states))ifencoder_hidden_statesisnotNone:# 交叉注意力key_layerself.transpose_for_scores(self.key(encoder_hidden_states))value_layerself.transpose_for_scores(self.value(encoder_hidden_states))else:# 自注意力key_layerself.transpose_for_scores(self.key(hidden_states))value_layerself.transpose_for_scores(self.value(hidden_states))# 注意力计算attention_scorestorch.matmul(query_layer,key_layer.transpose(-1,-2))/sqrt(head_size)attention_probsnn.Softmax(dim-1)(attention_scores)context_layertorch.matmul(attention_probs,value_layer)returncontext_layer2.4 前向传播流程definit_Qformer(num_query_token4,vision_width768,cross_attention_freq2):# 1. 配置 Q-Formerencoder_configBertConfig.from_pretrained(bert-base-uncased)encoder_config.encoder_widthvision_width# 视觉特征维度encoder_config.add_cross_attentionTrue# 添加交叉注意力encoder_config.cross_attention_freq2# 每2层插入交叉注意力encoder_config.query_lengthnum_query_token# 查询token数量# 2. 初始化 Q-FormerQformerBertLMHeadModel.from_pretrained(bert-base-uncased,configencoder_config)# 3. 初始化 Learnable Query Tokensquery_tokensnn.Parameter(torch.zeros(1,num_query_token,encoder_config.hidden_size))query_tokens.data.normal_(mean0.0,stdencoder_config.initializer_range)returnQformer,query_tokensdefforward(self,image_features):# image_features: [B, num_patches, vision_width] 来自视觉编码器# 1. 扩展查询token到 batchquery_tokensself.query_tokens.expand(image_features.shape[0],-1,-1)# query_tokens: [B, 4, 768]# 2. Q-Former 编码 (仅 query tokens 交叉注意力到视觉特征)query_outputself.Qformer.bert(query_embedsquery_tokens,encoder_hidden_statesimage_features,encoder_attention_maskimage_atts,)# 3. 提取查询token的输出query_featuresquery_output.last_hidden_state[:,:query_tokens.size(1),:]# query_features: [B, 4, 768]# 4. 投影到 LLM 输入维度image_featsself.llm_proj(query_features)# image_feats: [B, 4, 4096] (匹配 LLaVA 7B 维度)returnimage_feats2.5 输入输出示例输入# 来自视觉编码器的图像特征 (冻结)image_featurestorch.randn(1,65,768)# 65个patch每个768维image_attstorch.ones(1,65)# attention mask# Learnable Query Tokens (可学习参数)query_tokenstorch.randn(1,4,768)# 4个查询token输出# Q-Former 输出的紧凑视觉特征query_featurestorch.randn(1,4,768)# 4个精炼后的特征token# 投影到 LLM 兼容维度projected_featurestorch.randn(1,4,4096)# 用于与 LLM 交互3. 视觉编码器与 Q-Former 的协同工作3.1 完整流程┌─────────────────────────────────────────────────────────────────────┐ │ LMDrive 视觉处理管线 │ ├─────────────────────────────────────────────────────────────────────┤ │ │ │ [多视角图像 LiDAR] │ │ │ │ │ ▼ │ │ ┌─────────────────────────────┐ │ │ │ 视觉编码器 (Memfuser) │ │ │ │ - ResNet 提取图像特征 │ │ │ │ - PointPillar 提取LiDAR特征 │ │ │ │ - Transformer融合多模态 │ │ │ └─────────────────────────────┘ │ │ │ │ │ ▼ │ │ [融合特征: B × 65 × 768] │ │ │ │ │ ▼ │ │ ┌─────────────────────────────┐ │ │ │ Q-Former │ │ │ │ - Learnable Query Tokens │ │ │ │ - 交叉注意力提取关键信息 │ │ │ │ - 压缩特征维度 │ │ │ └─────────────────────────────┘ │ │ │ │ │ ▼ │ │ [精炼特征: B × 4 × 4096] → 与文本拼接 → LLM (LLaVA) │ │ │ └─────────────────────────────────────────────────────────────────────┘3.2 LMDrive 真实数据流根据drive.py中的forward方法真实的数据流向如下defforward(self,samples,inference_modeFalse,image_embedsNone):# 阶段1: 视觉编码器提取特征 (冻结)ifimage_embedsisNone:withtorch.no_grad():image_embedsself.visual_encoder(samples)# [B*t, 65, 768]image_embedsself.ln_vision(image_embeds)# 阶段2: Q-Former 精炼特征ifself.has_qformer:query_tokensself.query_tokens.expand(image_embeds.shape[0],-1,-1)# query_tokens: [B*t, 4, 768]# Q-Former 输入包含文本指令和查询tokentext_Qformerself.llm_tokenizer([iforiinsamples[text_input]for_inrange(t)],paddinglongest,max_lengthself.max_txt_len)Qformer_attstorch.cat([query_atts,text_Qformer.attention_mask],dim1)# Q-Former 编码 (文本 查询token 交叉注意力到视觉特征)query_outputself.Qformer.bert(text_Qformer.input_ids,attention_maskQformer_atts,query_embedsquery_tokens,encoder_hidden_statesimage_embeds,encoder_attention_maskimage_atts,)# 提取查询token的输出并投影到 LLM 维度image_embedsself.llm_proj(query_output.last_hidden_state[:,:4,:])# image_embeds: [B*t, 4, 4096]# 阶段3: 重塑时间维度image_embedsimage_embeds.view(bs,t,*image_embeds.size()[1:])# image_embeds: [B, t, 4, 4096]# 阶段4: 拼接文本与视觉特征inputs_embedsself.llm_model.get_input_embeddings()(text_input_tokens.input_ids)llm_inputstorch.cat([inputs_embeds[i][:text_len],image_embeds[i].view(t*4,-1),inputs_embeds[i][text_len:]])# 阶段5: LLM 预测hidden_statesself.llm_model(inputs_embedsllm_inputs)# 阶段6: 轨迹预测predicted_waypointsself.waypoints_predictor(hidden_states)predicted_end_probself.end_predictor(hidden_states)returnpredicted_waypoints,predicted_end_prob3.3 关键设计优势设计点优势视觉编码器冻结保留预训练知识避免过拟合降低训练成本Query Tokens 可学习自适应提取任务相关特征无需重新设计视觉模型交替交叉注意力平衡计算效率与信息提取能力特征维度压缩从 65 个视觉 patch 压缩到 4 个 query token降低 LLM 输入长度端到端可训练Query Tokens 和 Q-Former 参数可与 LLM 联合微调3.4 与 LLM 的接口defget_vision_features(self,images,lidar):# 1. 视觉编码器提取特征 (冻结)withtorch.no_grad():memfuser_featuresself.memfuser(images,lidar)# memfuser_features: [B, 65, 768]# 2. Q-Former 精炼特征query_featuresself.Qformer(query_embedsself.query_tokens,encoder_hidden_statesmemfuser_features,).last_hidden_state[:,:4,:]# query_features: [B, 4, 768]# 3. 投影到 LLM 输入维度vision_featuresself.llm_proj(query_features)# vision_features: [B, 4, 4096] (匹配 LLaVA 7B 维度)returnvision_features# 送入 LLMllm_inputtorch.cat([vision_features,text_embeddings],dim1)responseself.llm_model(llm_input)4. 算法创新点总结组件创新点Memfuser1. 多视角图像 LiDAR 深度融合2. View Embedding 区分视角3. HybridEmbed 适配不同 backboneQ-Former1. Learnable Query Tokens 主动查询2. 交替交叉注意力高效提取3. 冻结视觉编码器实现迁移学习整体架构1. 视觉特征 → 精炼特征 → LLM 的渐进式处理2. 模块化设计支持替换不同视觉模型3. 高效的跨模态信息传递

相关新闻