BigMac

BigMac:突破多模态大模型训练中的帕累托前沿

摘要

BigMac是原生多模场景下的流水并行训练新范式。它针对多模态大模型训练中计算效率与显存占用难以兼顾的问题,提出了依赖安全的嵌套流水线:以成熟的 LLM 流水线为主干,在不打乱LLM执行顺序的前提下,有序嵌入编码器和生成器计算,从而在不增加 LLM 流水线空泡、保持激活显存有界的同时,高效实现多模态流水训练。相比传统的流水并行实现方式,BigMac 在工程实现上进一步解耦了全局调度与运行时执行,并设计了一系列接口和工具链降低了模型接入与系统调优的成本。实验中,其训练速度较基线提升 1.08~1.9 倍,并在global batch size增大时保持的稳定显存占用。目前,BigMac已作为小红书dots多模态大模型训练的核心组件之一应用于生产中。开源地址:https://github.com/Dots-Infra/BigMac/

BigMac cover


多模态大语言模型(Multimodal large language models, MLLM)正在成为新一代 AI 系统的核心基础设施。相比只处理文本的 LLM,多模态模型需要把语言、图像、音频等不同类型的信息放到同一个模型里理解;在很多场景下,它们还要进一步生成图像、语音等内容。能力边界被打开了,训练系统的复杂度也随之上升。

难点在于,MLLM 通常不是一整块同构的 transformer,而是由多个形态差异很大的模块拼接起来。一个典型的多模态模型通常包含三个部分:模态编码器、LLM 主干,以及模态生成器。编码器把图像或音频等原始输入转换成 embedding。LLM 在得到的多模态 token 序列上进行推理。生成器则把 LLM 的输出映射回目标模态,例如用图像扩散模型生成像素。

Representative MLLM architecture

图 1:一个典型的 MLLM 架构,包含模态编码器、LLM 主干和模态生成器。

这种模块化架构带来了很强的表达能力,也把训练系统推向了普通 LLM 流水线很少遇到的复杂局面。编码器、LLM 和生成器在模型规模、执行模式、激活显存占用和偏好的并行策略上都不同。数据本身也不规则:某个 microbatch 可能只包含少量 vision tokens,另一个 microbatch 可能包含多得多的 vision tokens。即使 LLM 的序列长度固定,编码器和生成器面对的工作量仍然可能高度变化。

现有系统中的计算-显存两难

现有 MLLM 训练系统通常会选择两种设计之一。两种设计都有其合理性,但在规模变大后都会暴露明显瓶颈。

第一种设计是计算高效的。它把编码器和生成器计算从 LLM pipeline 中分离出来,类似 LongCat-Flash-Omni 中用于应对大规模多模态训练异构性的 modality-decoupled parallelism。例如,系统可能先对所有 microbatch 运行 encoder forward,保留这些 activation,然后再启动 LLM pipeline。这样可以让 LLM pipeline 不被模态模块的耗时波动打乱:编码器和生成器慢一点,不会直接在 LLM pipeline 内部制造 bubble。

然而,由于编码器 activation 必须一直保留到对应的梯度返回,activation 显存会随着 microbatch 数量增长。如果模型中还有生成器,情况会更糟:LLM activation 也可能需要一直保留到生成器计算结束。在生产规模模型中,这尤其昂贵,因为 LLM activation 往往远大于 encoder activation。

Compute-efficient baseline

图 2:计算高效的 pipeline。该设计将模态计算从 LLM pipeline 中分离出来,减少 bubble,但会保留大量 activation。

第二种设计是显存高效的。它把编码器和生成器整合进同一条 pipeline,把它们看作围绕 LLM 的首尾阶段;例如 Megatron Core 的多模态训练示例中,vision-language 模型作为一个独立的 pipeline stage,加入到了 LLM 的流水线中。这样可以缩短 activation 生命周期,因此显存占用更低。但是,所有模块现在都被 pipeline 依赖耦合在一起。如果某个 encoder 或 generator microbatch 很慢,LLM pipeline 就必须等待。如果生成器运行时间变化较大,pipeline 尾部就会产生 bubble。系统通过牺牲计算效率来节省显存。

Memory-efficient baseline

图 3:显存高效的 pipeline。该设计将所有模块整合到一条 pipeline 中,减少显存占用,但会产生跨模块 bubble。

这正是 BigMac 想要突破的 Pareto frontier。计算高效的系统速度快但显存开销大;显存高效的系统节省显存但容易产生 bubble。对于小规模训练任务,这种二选一可能还可以接受。但对于大规模多模态训练,尤其是包含模态生成器的训练,这种两难会成为瓶颈。

BigMac 的核心思想

BigMac 的出发点很简单:调度的主干仍然应该是 LLM pipeline。大规模 LLM 已经依赖 1F1B 或 interleaved 1F1B 等精心优化过的 pipeline schedule。这些 schedule 成熟、高效,并且与生产级 LLM 训练栈深度绑定。BigMac 不试图替换它们,而是把 LLM schedule 作为基础时间线。

BigMac 的思路是先稳住最重要的 LLM pipeline,再把编码器和生成器的计算插入到合适的位置。这里的“合适”,指的是输入已经准备好,而且插入这些计算不会打乱原本的 LLM 执行顺序。这样一来,LLM pipeline 可以持续推进,编码器和生成器的激活也能更早释放。我们称这种设计为依赖安全的嵌套流水线 (nested pipeline)

BigMac nested pipeline

图 4:BigMac 保留原始 LLM pipeline schedule,并把 encoder/generator 工作嵌入到依赖安全的位置。

这个设计给 BigMac 带来了两个重要性质。

第一,它保留了计算效率。由于编码器和生成器不再被强行塞进 LLM 流水线,作为独立的 pipeline stage 逐级推进,它们的耗时波动也不会沿着 LLM 流水线一路传下去。LLM 仍然按照它在计算高效系统中本该遵循的 schedule 运行。

第二,它限制了模态 activation 显存。BigMac 会在梯度就绪后尽快运行 encoder backward 和 generator backward。编码器不需要一直为所有 microbatch 保留 activation,直到 LLM pipeline 结束。生成器也不需要保留很长的 activation 尾部。从算法层面看,BigMac 将编码器和生成器 activation 显存降低到 O(1),同时保持 LLM activation 行为不变。

这就是整个流水线的核心:BigMac 不是在显存和 bubble 之间做交换,也不是用 bubble 换显存。它改变了 schedule 结构,让这两个目标不再必须相互冲突。

BigMac:让多模态流水训练真正落地

在真实的多模态大模型训练中,pipeline parallelism 的难点往往不只是“如何排 microbatch”。当 LLM、vision/audio encoder、diffusion generator 等异构模块需要一起训练,并扩展到多机多卡时,系统还必须解决一整套工程问题:异构模块怎么放,生成出来的 schedule 怎么接入 Megatron Core 等现有训练框架,模型代码怎么避免被 PP 细节侵入,以及当 pipeline 出现 bubble 或等待时如何定位瓶颈并快速迭代。

BigMac 关注的正是这些从“能设计 schedule”到“能真正训起来”的系统环节。它提供了三个关键能力:把 schedule 变成可见、可检查、可执行的全局计划;PP-transparent 接口让模型开发者仍然以模块化方式编写模型代码;schedule-aware 工具链则把 profiling、simulation 和可视化接入到性能诊断闭环中。下面我们分别展开这三点。

1. 把全局 schedule 摆到明面上

先看系统集成层。BigMac 的做法是把流水线调度从 rank-local runtime 控制流中抽出来,变成一张全局 operator 表。这样,encoder、LLM、generator 以及它们之间的通信不再散落在各个 rank 的执行逻辑里,而是先被统一表达成一张可以检查和执行的 schedule。

这和 Megatron Core 等成熟 LLM 训练框架中的 pipeline schedule 形成了鲜明对照。传统 schedule 通常从单个 pipeline rank 的视角编写。每个 rank 运行一段高度优化的 runtime 控制流:先用若干 forward microbatch 进行 warmup,随后进入 forward/backward 交替执行的 steady state,最后用 cooldown 完成剩余 backward。通信、activation buffer、梯度累积、loss 处理和 overlap 逻辑都交织在这段控制流中。

以 Megatron Core 0.17.1 为例,schedules.py 共 2,375 行,其中 forward_backward_pipelining_with_interleaving() 这个 interleaved pipeline schedule 函数就有 1,097 行。这并不是偶然复杂性;它反映了让标准 LLM pipeline 跑得快所需的 runtime 细节。但这也解释了为什么当我们引入 vision encoder、audio encoder 或 diffusion generator 等异构模块时,这类代码很难修改。加入这类模块并不只是加一次 encoder_forward() 调用。它会改变 microbatch 依赖、activation 生命周期、backward 就绪条件,以及跨 rank 通信匹配关系。

从高层看,传统的 rank-local pipeline runtime 可以粗略理解为:

def mcore_like_schedule_for_one_rank(rank):
    # The schedule is embedded in rank-local execution logic.

    for i in warmup_microbatches(rank):
        x = recv_forward_if_needed(rank)
        y = llm_forward(x)
        send_forward_if_needed(rank, y)
        save_activation(y)

    for i in steady_state_microbatches(rank):
        x = recv_forward_if_needed(rank)
        y = llm_forward(x)
        send_forward_if_needed(rank, y)

        dy = recv_backward_if_needed(rank)
        dx = llm_backward(dy)
        send_backward_if_needed(rank, dx)

    for i in cooldown_microbatches(rank):
        dy = recv_backward_if_needed(rank)
        dx = llm_backward(dy)
        send_backward_if_needed(rank, dx)

这段伪代码被刻意写得很简单。真实实现还需要处理 virtual pipeline stage、overlapped point-to-point communication、rank 边界条件、activation deallocation、loss reduction,以及分布式梯度同步。更深层的问题在于,调度策略和本地 runtime 机制交织在一起。如果我们想加入 encoder 或 generator 工作,就必须在 warmup、steady-state 和 cooldown 路径中同时更新代码,并维持新的依赖和通信顺序。用这种代码风格,很难直接回答全局问题:microbatch 7 的 encoder forward 在哪里运行?它的输出什么时候被 LLM 消费?encoder backward 什么时候可以安全释放保存的 activation?

BigMac 在 schedule 和 execution 之间采用了不同的接口。Scheduler 直接生成一张全局 operator 表,覆盖所有 pipeline rank、microbatch 和模块类型。这张表包含 LLM forward/backward operator、encoder forward/backward operator、generator forward/backward operator,以及模块边界上所需的通信。Executor 随后解释每个 rank 上的本地 operator 序列,并把每个 operator 分发给对应后端:LLM pipeline operator 交给 Megatron Core,模态 operator 交给 encoder 或 generator runtime,数据搬运交给通信后端。

def bigmac_schedule_globally(config):
    # The scheduler owns the global plan.
    schedule = BigMacScheduler(
        pp_size=config.pp_size,
        vpp_size=config.vpp_size,
        num_microbatches=config.num_microbatches,
        encoder_policy=config.encoder_policy,
        generator_policy=config.generator_policy,
    ).generate_schedule()

    schedule = add_communication_ops(schedule)
    check_deadlock(schedule)
    visualize_timeline(schedule)
    return schedule


def bigmac_execute_one_rank(rank, schedule):
    # The executor owns fine-grained local execution.
    for op in schedule.local_ops(rank):
        if op.kind == "LLM_FORWARD":
            run_llm_forward(op)
        elif op.kind == "LLM_BACKWARD":
            run_llm_backward(op)
        elif op.kind == "ENCODER_FORWARD":
            run_encoder_forward(op)
        elif op.kind == "ENCODER_BACKWARD":
            run_encoder_backward(op)
        elif op.kind == "GENERATOR_FORWARD":
            run_generator_forward(op)
        elif op.kind == "GENERATOR_BACKWARD":
            run_generator_backward(op)
        elif op.kind == "COMM":
            run_communication(op)

最终得到的 schedule 不再藏在 runtime 控制流里,而是一张可以打印、检查、模拟和可视化的执行表。下面的 timeline 展示了 PP=4 时的表达方式。它只是一个简化示意,并不代表完整 schedule;完整细节建议通过 BigMac 官方的可视化工具查看。 VF 表示 vision-encoder forward,F 表示 LLM forward,GF/GB 表示 generator forward/backward,B 表示 LLM backward,VB 表示 vision-encoder backward:

Time    0       1       2       3       4       5       ...     later
Rank 0  VF0     VF4     F0      F1      F2      F3      ...     B* / GF* / GB* / VB*
Rank 1  VF1     VF5     IDLE    F0      F1      F2      ...     B* / GF* / GB* / VB*
Rank 2  VF2     VF6     IDLE    IDLE    F0      F1      ...     B* / GF* / GB* / VB*
Rank 3  VF3     VF7     IDLE    IDLE    IDLE    F0      ...     B* / GF* / GB* / VB*

这种拆分给 BigMac 带来了两个实际优势。第一,调度策略变得可见、可检查。我们可以直接看到 encoder、LLM 和 generator 如何在所有 rank 上交错执行,而不需要从一段很长的 rank-local runtime 函数中反推出全局行为。第二,执行仍然对后端友好。LLM operator 可以继续复用 Megatron Core 等优化过的 pipeline runtime,而模态模块可以保留自己的 data-parallel、FSDP 或 optimizer 实现。Schedule 也可以在不重写模型 runtime 的情况下加入通信 operator、进行死锁检查。

2. 让模型代码自然接入 PP

在多模态训练里,系统工程师和算法工程师本来就需要紧密协作。算法工程师会不断调整 encoder、LLM、generator 的连接方式、loss 设计和数据形态;系统工程师则要把这些模块放进 PP/TP/DP/FSDP 等并行策略中,并处理通信、activation 生命周期和调度效率。问题在于,传统 PP 系统一旦扩展到多模态,这条协作边界很容易变得模糊:一次模型结构改动可能要求重写 stage 划分和 send/recv 逻辑,系统侧的优化也可能反过来侵入模型代码。

仅仅让系统工程师能改 schedule 还不够;如果算法工程师每次 scale up 都要理解 PP runtime,BigMac 仍然不是一个好用的训练系统。BigMac 的第二个关键能力,就是对算法工程师尽量无感的 pipeline-parallelism 接口。

多模态模型的实验通常先从单卡或 data-parallel 版本开始:算法工程师关心的是 encoder 如何产生 feature,LLM 如何消费这些 feature,generator 如何基于 LLM 输出计算 loss。但当实验需要扩展到 pipeline parallelism 时,传统系统往往要求模型作者把这些逻辑拆进不同 pipeline stage,手动处理 microbatch、send/recv、activation buffer 和 gradient handoff。这样一来,scale up 不再只是扩大训练规模,而变成了一次分布式 runtime 改造。

BigMac 希望把这部分复杂度从模型代码中移走。用户仍然可以用接近普通训练代码的方式描述模块边界:

PP-transparent interface

图 5:BigMac 的 pipeline-parallelism-transparent 接口示意。算法工程师描述模块边界,BigMac 在底层处理 schedule、handoff 和通信。

在这个接口下,算法工程师只需要说明每个模块生产什么、消费什么;BigMac 负责把这些模块接入全局 schedule,并在底层处理 pipeline stage、activation handoff、gradient handoff 和跨设备通信。换句话说,BigMac 并不是让系统里不存在流水并行,而是让流水并行不再侵入算法工程师的开发主循环。一个已经在单卡或 data-parallel 环境中验证过的多模态实验,可以更自然地扩展到 pipeline-parallel training;同时,系统工程师仍然可以在 executor 层接入 Megatron Core、DDP/FSDP 和高性能通信实现,继续优化调度、通信和资源利用,而不需要污染模型代码。

3. 用 schedule-aware 工具链定位瓶颈

BigMac 的最后一个关键能力,是一套理解 schedule 结构的 profiler、simulator 和可视化工具链。对于大规模多模态流水并行训练来说,性能问题很少能只靠 iteration time 或几行日志定位:bubble 可能来自某个慢 microbatch,可能来自 encoder/generator 的运行时间波动,也可能来自一次 activation handoff、gradient handoff 或跨 rank 通信等待。工程同学真正需要的是把一次训练 iteration 拆回 operator 级别,看清楚每个 rank 在每个时间点到底在执行什么、哪里空转、哪个依赖正在阻塞后续计算。

PP profiler workflow

图 6:传统性能排查通常需要下载并手动关联多个 rank 的重型 trace;BigMac PP profiler 将这些信息整理成 schedule-aware 的 pipeline 诊断流程。

BigMac executor 会记录每个 operator 的执行时间,并导出 per-rank timeline / trace,如图 7 所示。通过这个 trace,工程同学可以直接观察 encoder forward/backward、LLM forward/backward、generator forward/backward 和通信操作在不同 rank 上如何交错执行,从而判断 pipeline bubble 是由 compute imbalance、communication wait、模块 handoff,还是不合适的 microbatch grouping 引起的。

Pipeline trace example

图 7:由 per-operator 执行时间生成的 pipeline trace 示例。

我们也提供了一个可交互查看的 PP profiler trace 示例。下载后可以直接在 Perfetto UI 中打开,观察不同 rank、不同 operator 之间的时间线和依赖关系。

在 profiler 之外,BigMac 还提供 simulator 来支持更快的并行策略迭代。Profiler 告诉我们当前训练为什么慢;simulator 则让我们在启动下一次昂贵训练任务之前,先尝试不同的 PP/VPP 配置、microbatch 数量、模块放置和 scheduling policy,预估它们对 bubble 和吞吐的影响。这样,并行策略优化就不再完全依赖大规模训练试错,而可以先在 schedule 层面完成快速探索。

这三项能力合在一起,才是 BigMac 从一个 schedule 变成训练系统的关键:在全局 schedule 这一层,scheduler 让全局流水排布可控,executor 把它落到现有高性能后端上;PP-transparent 接口让模型代码保持模块化;profiler 和 simulator 则把执行结果反馈回策略迭代。对于多模态 + pipeline parallelism 这样的复杂训练任务,BigMac 解决的不是某一个局部优化,而是从表达、执行到诊断迭代的完整闭环。

实验结果

我们用两个代表性训练负载评估 BigMac。第一个是 MLLM-Understanding,代表多模态理解训练:模型使用 encoder 将图像输入转换成 token,再由 LLM 完成理解和推理,不包含模态生成器。这个负载使用 Qwen3-30B-A3B 作为 LLM backbone,并使用一个 1.3B 参数的 ViT encoder。第二个是 MLLM-Generation,代表同时包含理解和生成路径的训练:它使用相同的 LLM 和 encoder,但增加了一个 20B 参数的 MMDiT generator。两个负载都使用 8K LLM sequence length,并且所有模块都参与训练。

在 MLLM-Understanding 上,相比计算高效 baseline Optimus,BigMac 实现了 1.08x-1.1x 的训练加速;相比显存高效 baseline Megatron-DistTrain,实现了 1.6x-1.9x 的训练加速。相比 Megatron-DistTrain 的加速来自消除跨模块 pipeline 干扰。相比 Optimus 的优势更微妙:BigMac 避免了 activation 显存压力,而这种压力会随着 batch size 增大让计算高效设计越来越昂贵。

MLLM-understanding results

图 8:MLLM-Understanding 训练负载上的整体性能。

显存趋势和速度提升同样重要。随着 per-GPU batch size 增加,BigMac 的 peak memory 保持稳定,类似显存高效 baseline。相比之下,Optimus 会在 LLM pipeline 期间保留 encoder activation;它的显存使用快速增长,并最终在更大的 batch size 下 OOM。

这里的 MLLM-Generation 指的是带模态生成器的多模态训练:LLM 不只是输出用于理解任务的表示,还要把中间结果交给 MMDiT generator,由 generator 继续计算生成侧的训练目标。在这个负载上,差异变得更加明显。Generator 会让计算高效设计更难扩展,因为 LLM activation 可能需要一直保留到 generator computation 完成。在论文实验中,Optimus 在 MLLM-Generation 负载的所有测试 batch size 上都会 OOM。BigMac 通过及时运行 generator backward 并快速释放 generator 侧 activation 避免了这个问题。

MLLM-generation results

图 9:MLLM-Generation 训练负载上的整体性能。

相比 Megatron-DistTrain,BigMac 在 MLLM-Generation 负载上实现了 1.5x-1.9x 的训练加速,同时保持稳定显存使用。这正是 nested pipeline 最有价值的场景:系统必须同时处理 encoder 和 generator 依赖,但又不能承受大量 activation retention 或严重 pipeline bubble。

总结

多模态大模型训练的难点,并不只是模型更大或数据更复杂,而是不同模态模块把流水线训练限制在了一个尴尬的帕累托前沿内。BigMac 的核心是突破这个前沿。它保留 LLM pipeline 作为稳定主干,只在依赖满足且不打乱 LLM 执行顺序的位置嵌入 encoder 和 generator 计算。这样,系统既能维持 LLM 流水的计算效率,又能尽早释放模态模块的 activation。更重要的是,BigMac 不只给出一个 schedule,还把 schedule 变成可见、可检查、可执行的全局计划,并配套 PP-transparent 接口和 schedule-aware 工具链,让这一设计真正进入可开发、可调试、可部署的训练系统。

论文与引用

论文: BigMac: Breaking the Pareto Frontier of Compute and Memory in Multimodal LLM Training

如果 BigMac 对你的研究或系统有帮助,欢迎引用:

@article{zhang2026bigmac,
  title={BigMac: Breaking the Pareto Frontier of Compute and Memory in Multimodal LLM Training},
  author={Zili Zhang and Chengxu Yang and Shenglong Zhang and Chenyu Wang and Yufan Zhang and Tuo Dai and Zhouyang Li and Yuhong Ge and Chao Jin and Xin Jin and Yuliang Liu},
  journal={arXiv preprint arXiv:2605.25451},
  year={2026},
  doi={10.48550/arXiv.2605.25451}
}