VLA-0 是一款开创性的视觉 - 语言动作(Vision-Language-Action, VLA)模型,其核心理念是零架构修改适配主流预训练VLM模型,无需改造模型结构、分词器和训练逻辑,即可将纯文本大模型快速升级为具备视觉感知、语言理解与动作执行能力的 SOTA 级 VLA 模型。

                                               ———VLA-0: Building State-of-the-Art VLAs with Zero Modification

这篇文章的核心技术是不修改底层视觉语言模型(VLM)的架构,直接将机器人动作表示为文本字符串,利用 VLM 的原生文本生成能力构建视觉 - 语言 - 动作模型(VLA),即 VLA-0。

本文对VLA-0的代码进行整理并且重构,训练速度提升20倍,模型可替换,搭建了一个基础框架方便大家做科研。

支持功能:deepspeed,lora,finetune,multiple-gpus,multiple-datasets

代码仓库:https://github.com/garlic-byte/VLA-0-Speedup.githttps://github.com/garlic-byte/VLA-0-Speedup.git

一、 核心技术内容

  1. 输入输出设计
    • 输入包含系统提示、任务指令文本和多视角图像,无需对 VLM 做任何结构改动。
    • 输出将连续的机器人动作(如关节角度、末端执行器坐标)归一化到固定整数范围,再转化为空格分隔的文本字符串。
  2. 关键训练与推理策略
    • 掩码动作增强:训练时随机掩码目标动作字符串中的部分字符,强制模型依赖视觉观察和任务指令推理动作,而非依赖自回归的序列补全。
    • 集成预测:推理时融合多个历史时间步对当前动作的预测结果,提升动作输出的稳定性。

二、 核心创新点

  1. 极简架构设计,零修改 VLM
    • 摒弃传统 VLA 的三类复杂方案,包括离散动作令牌化、新增生成式动作头、自定义架构。
    • 直接复用 VLM 的文本生成能力,无需改动词汇表、添加新网络层或设计专用分词器,最大程度保留 VLM 原有的语言理解和视觉 grounding 能力。
  2. 端到端动作文本生成,超越两阶段方案
    • 不同于 LLARVA 等两阶段模型,VLA-0 无需先生成 2D 轨迹再预测动作,可直接端到端生成完整的机器人动作文本序列。
    • 该设计在保证动作精度的同时,简化了模型流程,降低了训练和部署的复杂度。
  3. 轻量化方案实现 SOTA 性能,无需大规模预训练
    • 在 LIBERO 基准测试中,未经过大规模机器人动作数据预训练的 VLA-0,性能超过了所有同量级训练的模型,还优于多款大规模预训练的 VLA 模型。
    • 在真实机器人实验中,VLA-0 相比基于大规模数据集预训练的 SmolVLA,平均成功率提升 12.5 个百分点,验证了方案的实用性和泛化性。

三、重构训练架构

1. 批量对动作进行掩码,提升效率
    def __call__(self, features: List[Dict[str, any]]) -> BatchFeature:
        """
        Apply random mask to actions from VLM inputs.
        :param features: List of VLM inputs which contains text, images, question_length.
        :return: Integrate features into a batch. 
        """
        text_ls = [element['text'] for element in features]
        images_ls = [element['image'] for element in features]
        qus_len_ls = [element['qus_len'] for element in features]

        # Integrate text and images into a batch
        vlm_inputs = self.processor(
            text=text_ls, images=images_ls, return_tensors="pt", padding=True
        )

        labels = vlm_inputs["input_ids"].clone()
        labels[labels == 151643] = -100
        batch_size, seq_len = labels.shape
        qus_len_tensor = torch.tensor(qus_len_ls)

        # Create mask for actions
        pos_id = torch.arange(seq_len).unsqueeze(0).repeat(batch_size, 1)
        action_mask = pos_id > qus_len_tensor.unsqueeze(1)
        # element equal to -100 will not calculate the loss
        labels[~action_mask] = -100
        
        # Create random mask
        random_values = torch.rand((batch_size, seq_len))
        action_mask &= random_values < self.mask_ratio

        # Apply mask into labels and input_ids
        labels[action_mask] = -100
        vlm_inputs["input_ids"][action_mask] = 30 # element equal to 30 represent '?'

        # Reshape vlm inputs to batch shape
        vlm_inputs["input_ids"] = vlm_inputs["input_ids"].view(batch_size, 1, seq_len)
        vlm_inputs["attention_mask"] = vlm_inputs["attention_mask"].view(batch_size, 1, seq_len)
        vlm_inputs["pixel_values"] = vlm_inputs["pixel_values"].view(batch_size, -1, vlm_inputs["pixel_values"].size(1))
        vlm_inputs["image_grid_thw"] = vlm_inputs["image_grid_thw"].view(batch_size, -1, vlm_inputs["image_grid_thw"].size(1))
        vlm_inputs["labels"] = labels.view(batch_size, 1, seq_len)

        return BatchFeature(data={**vlm_inputs})
2. 使用Qwen3-VL作为基座模型,可拆卸
    def _setup_model(self):
        nvtx.range_push("Load model")
        device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
        assert device.type == "cuda", "GPUs is not supported."
        model = Qwen3VLForConditionalGeneration.from_pretrained(
            self.config.model_path, dtype=self.config.dtype, device_map=device
        )

        # Freeze all parameters
        for param in model.parameters():
            param.requires_grad = False

        finetune_modules = []
        # Activate parameters according configuration
        # Use Lora for training model

        if self.config.lora_rank > 1:
            from peft import LoraConfig, get_peft_model

            # Only train part of language module for lora tune as default
            target_modules = ["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"]
            lora_config = LoraConfig(
                r=self.config.lora_rank,
                lora_alpha=self.config.lora_alpha,
                lora_dropout=self.config.lora_dropout,
                bias="none",
                target_modules=target_modules,
            )
            model = get_peft_model(model, lora_config)

            finetune_modules.append("Lora: ")
            finetune_modules.append(target_modules)
        # Only training partly parameters of model
        else:
            if self.config.tune_llm:
                for param in model.model.language_model.parameters():
                    param.requires_grad = True
                finetune_modules.append("Language modules")
            if self.config.tune_visual:
                for param in model.model.visual.parameters():
                    param.requires_grad = True
                finetune_modules.append("Visual modules")

        total_params = sum(p.numel() for p in model.parameters())
        total_trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
        logging_model_load(
            model_path=self.config.model_path,
            finetune_modules=finetune_modules,
            total_params=total_params,
            total_trainable_params=total_trainable_params,
        )
        nvtx.range_pop()
        return model
3. 使用线程提前加载数据集,提升训练速度20倍
    def _start_get_shard(self):
        """Get shard from dataset through thread."""
        if self.cur_sample_index >= len(self.filtered_sample_indices):
            self._reset_environment()

        # Sample from filtered_sample_indices
        index_dataset, indices_shard = self.filtered_sample_indices[self.cur_sample_index]
        self._cache_job = self._executor.submit(
            self.datasets[index_dataset].get_shard, indices_shard
        )

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐