transfusion-pytorch

lucidrainsMIT活跃维护

用 PyTorch 复现 MetaAI 的 Transfusion:在同一多模态模型里同时预测下一个 token 和扩散生成图像,把语言建模与图像扩散统一到一个 Transformer 中。

Pytorch implementation of Transfusion, "Predict the Next Token and Diffuse Images with One Multi-Modal Model", from MetaAI

0.16.3发布于 2026-01-27 12:25 UTC1,412star77fork同步于 2026-11-07 07:31 UTC

怎么上手

由 README 提炼,执行前请确认
pip install transfusion-pytorch
硬件要求按 README 说明

README 未说明显存要求;示例中可将模型 .cuda() 运行,但未列出支持的 GPU 厂商或型号

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

用 PyTorch 实现 Transfusion 多模态模型,文本预测下一 token、图像用流匹配生成

用 PyTorch 复现 MetaAI 的 Transfusion:在同一多模态模型里同时预测下一个 token 和扩散生成图像,把语言建模与图像扩散统一到一个 Transformer 中。

核心能力

  • 文本走自回归、模态走流匹配,统一在一个 Transformer 里训练
  • 用 torch.long 表示文本、torch.float 表示模态,自动区分类型
  • 支持多模态,可为每种模态指定独立 latent 维度和默认形状
  • 可挂载自定义 encoder/decoder,自动完成图像编解码
  • sample_many 批量并行采样,共享 KV 缓存和 ODE 轨迹

容易踩的坑

跑示例需额外安装依赖:pip install .[examples];遇到 safetensors 相关报错需升级 diffusers transformers accelerate scipy ftfy safetensors;README 未说明默认端口或需额外下载模型

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本0.16.3
  1. 0.16.3最新正式版2026-01-27 · 2026-01-27 12:25 UTC
  2. 0.16.22026-01-23 · 2026-01-23 22:54 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/lucidrains/transfusion-pytorch/compare/0.16.1...0.16.2

  3. 0.16.12026-01-19 · 2026-01-19 18:11 UTC
    查看更新说明
  4. 0.16.02026-01-19 · 2026-01-19 15:59 UTC
    查看更新说明

    What's Changed

    New Contributors

    Full Changelog: https://github.com/lucidrains/transfusion-pytorch/compare/0.15.3...0.16.0

  5. 0.15.32026-01-08 · 2026-01-08 15:04 UTC
    查看更新说明

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    Transfusion - Pytorch

    Pytorch implementation of Transfusion, "Predict the Next Token and Diffuse Images with One Multi-Modal Model", from MetaAI.

    In this repo, we will substitute diffusion with flow matching given the success of Flux from Black Forest Labs (but will keep the original paper title given Transflow does not have the same ring). This repository will also attempt to extend to any number of modalities.

    Appreciation

    • Pranoy for adding classifier free guidance!

    Install

    $ pip install transfusion-pytorch
    

    Usage

    One modality, say images

    from torch import randint, randn
    from transfusion_pytorch import Transfusion
    
    model = Transfusion(
        num_text_tokens = 256,
        dim_latent = 384,
        modality_default_shape = (4,),  # fallback, in the case the language model did not produce a valid modality shape
        transformer = dict(
            dim = 512,
            depth = 8
        )
    )
    
    # any torch.long is text, torch.float is modalities
    
    text_and_images = [
        [randint(0, 256, (16,)), randn(4, 384), randint(0, 256, (8,)), randn(6, 384)],
        [randint(0, 256, (16,)), randn(7, 384), randint(0, 256, (5,)), randn(2, 384), randint(0, 256, (9,))]
    ]
    
    loss = model(text_and_images)
    
    loss.backward()
    
    # after much training
    
    one_multimodal_sample = model.sample()
    

    Multiple different modalities

    from torch import randint, randn
    from transfusion_pytorch import Transfusion
    
    model = Transfusion(
        num_text_tokens = 256,
        dim_latent = (384, 192),                 # specify multiple latent dimensions
        modality_default_shape = ((4,), (2,)),   # default shapes for first and second modality
        transformer = dict(
            dim = 512,
            depth = 8
        )
    )
    
    # then for the Tensors of type float, you can pass a tuple[int, Tensor] and specify the modality index in the first position
    
    # any torch.long is text, torch.float is modalities
    
    text_images_and_audio = [
        [randint(0, 256, (16,)), (0, randn(4, 384)), randint(0, 256, (8,)), (1, randn(6, 192))],
        [randint(0, 256, (16,)), randn(7, 384), randint(0, 256, (5,)), (1, randn(2, 192)), randint(0, 256, (9,))]
    ]
    
    loss = model(text_images_and_audio)
    
    loss.backward()
    
    # after much training
    
    one_multimodal_sample = model.sample()
    

    Automatically taking care of encoding and decoding of images

    import torch
    from torch import nn, randint, randn
    from transfusion_pytorch import Transfusion, print_modality_sample
    
    mock_encoder = nn.Conv2d(3, 384, 3, padding = 1)
    mock_decoder = nn.Conv2d(384, 3, 3, padding = 1)
    
    model = Transfusion(
        num_text_tokens = 12,
        dim_latent = 384,
        channel_first_latent = True,
        modality_default_shape = (4, 4),
        modality_encoder = mock_encoder,
        modality_decoder = mock_decoder,
        transformer = dict(
            dim = 512,
            depth = 8
        )
    )
    
    text_and_images = [
        [
            randint(0, 12, (16,)),  # 16 text tokens
            randn(3, 8, 8),         # (8 x 8) 3 channeled image
            randint(0, 12, (8,)),   # 8 text tokens
            randn(3, 7, 7)          # (7 x 7) 3 channeled image
        ],
        [
            randint(0, 12, (16,)),  # 16 text tokens
            randn(3, 8, 5),         # (8 x 5) 3 channeled image
            randint(0, 12, (5,)),   # 5 text tokens
            randn(3, 2, 16),        # (2 x 16) 3 channeled image
            randint(0, 12, (9,))    # 9 text tokens
        ]
    ]
    
    loss = model(text_and_images)
    
    loss.backward()
    
    # after much training
    
    one_multimodal_sample = model.sample()
    
    print_modality_sample(one_multimodal_sample)
    

    Sampling a batch of interleaved text + modality samples in parallel, with sample_many

    sample_many decodes an entire batch of samples concurrently: all samples currently decoding text share a single kv-cached forward pass, and all samples currently decoding a modality share a single joint odeint trajectory (one forward pass per ode evaluation, with each sample keeping its own shape, length and modality type). sample_one walks each sample through the same state machine serially - sample_many is the batched equivalent.

    import torch
    from transfusion_pytorch import Transfusion
    
    model = Transfusion(
        num_text_tokens = 256,
        dim_latent = 384,
        modality_default_shape = (4,),
        transformer = dict(
            dim = 512,
            depth = 8
        )
    )
    
    # a batch is a list of prompts, each taking the same form as the `prompt` of `sample_one` -
    # a list of text tensors / (modality_type, tensor) tuples, a raw tensor or tuple, or `None`
    
    prompts = [
        torch.randint(0, 256, (16,)),                                   # raw text prompt
        (0, torch.randn(4, 384)),                                       # raw modality prompt
        None,                                                           # empty prompt
        [torch.randint(0, 256, (8,)), (0, torch.randn(6, 384))],        # interleaved text + modality
    ]
    
    samples = model.sample_many(prompts, max_length = 2048, cfg_scale = 3.)
    

    the samples come back as a list of ModalitySamples, one per prompt. the kv cache is always used (the cache_kv = True code path of sample_one), and each sample keeps its own max length budget, so one sample finishing early does not hold up the rest of the batch.

    To pretrain on language first, just pass in your text as type Int['batch seq']

    import torch
    from transfusion_pytorch import Transfusion
    
    model = Transfusion(
        num_text_tokens = 256,
        dim_latent = 384,
        transformer = dict(
            dim = 512,
            depth = 8,
        )
    ).cuda()
    
    text = torch.randint(0, 256, (2, 1024)).cuda()
    
    loss = model(text)
    loss.backward()
    
    # after much training
    
    sampled = model.generate_text_only(text[:, :1], 1024)
    

    Examples

    To run any of the examples train_{example_name}.py in the project root, simply install dependencies first as so

    $ pip install .[examples]
    

    If you run into some weird error with safetensors, run this too

    $ pip install -U diffusers transformers accelerate scipy ftfy safetensors
    

    Forcing a modality at the start of generation

    To force the first generated thing to be a specific modality - skipping text decoding at the start - pass force_modality_at_start to sample / sample_many with the modality type, or a (modality_type, shape) tuple to also force its shape. for example, prompt with some text, then a video (modality 0, channel first 3d latent), and force a 1d action of chunk length 32 (modality 1):

    import torch
    from transfusion_pytorch import Transfusion
    
    model = Transfusion(
        num_text_tokens = 256,
        dim_latent = (16, 8),
        modality_default_shape = ((4, 4, 4), (16,)),  # (video, action)
        channel_first_latent = (True, False),
        transformer = dict(
            dim = 512,
            depth = 8
        )
    )
    
    # ICL for human to robot - a human demonstrates the task on video, then the robot actions are generated in-context, no finetuning
    
    text = torch.randint(0, 256, (16,))                                 # some text prompt
    human_demo_video = torch.randn(16, 4, 4, 4)                         # channel first video latent - (latent dim, frames, height, width)
    
    samples = model.sample_many(
        [[text, (0, human_demo_video)]],                                # one prompt: text, then the human demonstration video
        force_modality_at_start = (1, (32,)),                           # force a 1d robot action chunk of length 32
        return_without_prompt = True,                                   # just the decoded modalities, no prompt
        cfg_scale = 3.,
    )
    
    # modality items come back with named attributes - `.modality_type`, `.tensor`, `.loss_weight`
    
    robot_actions = samples[0][0].tensor                                # the forced robot actions, of shape (32, 8)
    

    the batch can mix prompts of different text and video lengths - each sample still gets its forced action in the same shape.

    forcing only the modality type (force_modality_at_start = 1) falls back to the modality's default shape (or fixed_modality_shape).

    Citations

    @inproceedings{Zhou2024TransfusionPT,
        title  = {Transfusion: Predict the Next Token and Diffuse Images with One Multi-Modal Model},
        author = {Chunting Zhou and Lili Yu and Arun Babu and Kushal Tirumala and Michihiro Yasunaga and Leonid Shamis and Jacob Kahn and Xuezhe Ma and Luke Zettlemoyer and Omer Levy},
        year   = {2024},
        url    = {https://api.semanticscholar.org/CorpusID:271909855}
    }
    
    @misc{Rubin2024,
        author  = {Ohad Rubin},
        url     = {https://medium.com/@ohadrubin/exploring-weight-decay-in-layer-normalization-challenges-and-a-reparameterization-solution-ad4d12c24950}
    }
    
    @article{Nguyen2024MinPS,
        title   = {Min P Sampling: Balancing Creativity and Coherence at High Temperature},
        author  = {Minh Nguyen and Andrew Baker and Andreas Kirsch and Clement Neo},
        journal = {ArXiv},
        year    = {2024},
        volume  = {abs/2407.01082},
        url     = {https://api.semanticscholar.org/CorpusID:270870613}
    }
    
    @article{Bao2022AllAW,
        title   = {All are Worth Words: A ViT Backbone for Diffusion Models},
        author  = {Fan Bao and Shen Nie and Kaiwen Xue and Yue Cao and Chongxuan Li and Hang Su and Jun Zhu},
        journal = {2023 IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},
        year    = {2022},
        pages   = {22669-22679},
        url     = {https://api.semanticscholar.org/CorpusID:253581703}
    }
    
    @inproceedings{Zhao2024MonoFormerOT,
        title     = {MonoFormer: One Transformer for Both Diffusion and Autoregression},
        author    = {Chuyang Zhao and Yuxing Song and Wenhao Wang and Haocheng Feng and Errui Ding and Yifan Sun and Xinyan Xiao and Jingdong Wang},
        year      = {2024},
        url       = {https://api.semanticscholar.org/CorpusID:272832492}
    }
    
    @article{Yang2024ConsistencyFM,
        title   = {Consistency Flow Matching: Defining Straight Flows with Velocity Consistency},
        author  = {Ling Yang and Zixiang Zhang and Zhilong Zhang and Xingchao Liu and Minkai Xu and Wentao Zhang and Chenlin Meng and Stefano Ermon and Bin Cui},
        journal = {ArXiv},
        year    = {2024},
        volume  = {abs/2407.02398},
        url     = {https://api.semanticscholar.org/CorpusID:270878436}
    }
    
    @inproceedings{Zhou2024ValueRL,
        title   = {Value Residual Learning For Alleviating Attention Concentration In Transformers},
        author  = {Zhanchao Zhou and Tianyi Wu and Zhiyun Jiang and Zhenzhong Lan},
        year    = {2024},
        url     = {https://api.semanticscholar.org/CorpusID:273532030}
    }
    
    @inproceedings{Duvvuri2024LASERAW,
        title   = {LASER: Attention with Exponential Transformation},
        author  = {Sai Surya Duvvuri and Inderjit S. Dhillon},
        year    = {2024},
        url     = {https://api.semanticscholar.org/CorpusID:273849947}
    }
    
    @inproceedings{Dong2024HymbaAH,
        title   = {Hymba: A Hybrid-head Architecture for Small Language Models},
        author  = {Xin Dong and Y. Fu and Shizhe Diao and Wonmin Byeon and Zijia Chen and Ameya Mahabaleshwarkar and Shih-Yang Liu and Matthijs Van Keirsbilck and Min-Hung Chen and Yoshi Suhara and Yingyan Lin and Jan Kautz and Pavlo Molchanov},
        year    = {2024},
        url     = {https://api.semanticscholar.org/CorpusID:274166163}
    
    @article{Zhu2024HyperConnections,
        title   = {Hyper-Connections},
        author  = {Defa Zhu and Hongzhi Huang and Zihao Huang and Yutao Zeng and Yunyao Mao and Banggu Wu and Qiyang Min and Xun Zhou},
        journal = {ArXiv},
        year    = {2024},
        volume  = {abs/2409.19606},
        url     = {https://api.semanticscholar.org/CorpusID:272987528}
    }
    
    @article{Zhu2025FracConnectionsFE,
        title   = {Frac-Connections: Fractional Extension of Hyper-Connections},
        author  = {Defa Zhu and Hongzhi Huang and Jundong Zhou and Zihao Huang and Yutao Zeng and Banggu Wu and Qiyang Min and Xun Zhou},
        journal = {ArXiv},
        year    = {2025},
        volume  = {abs/2503.14125},
        url     = {https://api.semanticscholar.org/CorpusID:277104144}
    }
    
    @misc{li2025basicsletdenoisinggenerative,
        title   = {Back to Basics: Let Denoising Generative Models Denoise},
        author  = {Tianhong Li and Kaiming He},
        year    = {2025},
        eprint  = {2511.13720},
        archivePrefix = {arXiv},
        primaryClass = {cs.CV},
        url     = {https://arxiv.org/abs/2511.13720},
    }
    
    @misc{chefer2026self,
        title   = {Self-Supervised Flow Matching for Scalable Multi-Modal Synthesis},
        author  = {Hila Chefer and Patrick Esser and Dominik Lorenz and Dustin Podell and Vikash Raja and Vinh Tong and Antonio Torralba and Robin Rombach},
        year    = {2026},
        url     = {https://bfl.ai/research/self-flow},
        note    = {Preprint}
    }
    
    @misc{kimiteam2026attentionresiduals,
        title   = {Attention Residuals},
        author  = {Kimi Team and Guangyu Chen and Yu Zhang and Jianlin Su and Weixin Xu and Siyuan Pan and Yaoyu Wang and Yucheng Wang and Guanduo Chen and Bohong Yin and Yutian Chen and Junjie Yan and Ming Wei and Y. Zhang and Fanqing Meng and Chao Hong and Xiaotong Xie and Shaowei Liu and Enzhe Lu and Yunpeng Tai and Yanru Chen and Xin Men and Haiqing Guo and Y. Charles and Haoyu Lu and Lin Sui and Jinguo Zhu and Zaida Zhou and Weiran He and Weixiao Huang and Xinran Xu and Yuzhi Wang and Guokun Lai and Yulun Du and Yuxin Wu and Zhilin Yang and Xinyu Zhou},
        year    = {2026},
        eprint  = {2603.15031},
        archivePrefix = {arXiv},
        primaryClass = {cs.CL},
        url     = {https://arxiv.org/abs/2603.15031},
    }