MLM之Emu3:Emu3(仅需下一个Token预测)的简介、安装和使用方法、案例应用之详细攻略
导读:这篇论文介绍了Emu3,一个基于单一Transformer架构,仅使用下一个token预测进行训练的多模态模型。
>> 背景痛点:
多模态任务的瓶颈: 现有的多模态模型在生成和感知任务上,主要依赖于复杂的扩散模型(如Stable Diffusion)或组合方法(如CLIP结合LLM),这些方法通常结构复杂,难以扩展。 下一个token预测方法虽然在语言模型领域取得了巨大成功,但在多模态领域应用有限,难以达到与特定任务模型相当的性能。
>> 具体的解决方案:Emu3是一个全新的多模态模型套件,它完全摒弃了扩散模型和组合方法,仅依靠下一个token预测进行训练。 通过将图像、文本和视频标记到一个离散空间,Emu3在一个单一的Transformer解码器中进行端到端训练。
>> 核心思路步骤:
● 数据标记化: 将图像、文本和视频数据标记成离散的token。 这需要一个强大的视觉标记器,论文中使用了基于SBER-MoVQGAN的视觉标记器,能够将图像和视频压缩成离散的token。
● 多模态数据融合: 将文本token和视觉token融合成文档式的输入,用于训练Transformer模型。 使用了特殊的token来区分不同模态的数据。
● 下一个token预测: 使用标准的交叉熵损失函数进行下一个token预测训练。 为了避免视觉token主导训练过程,视觉token的损失权重设置为0.5。
● 预训练: 分两个阶段进行预训练。第一阶段使用文本和图像数据,第二阶段加入视频数据。 使用了张量并行、上下文并行和数据并行等技术来加速训练。
● 后训练: 针对图像生成和视觉语言理解任务进行后训练。 图像生成使用了质量微调 (QFT) 和直接偏好优化 (DPO) 来提升生成质量和与人类偏好的对齐程度。 视觉语言理解则分两个阶段进行,先进行图像到文本的训练,再进行指令微调。
>> 优势:
● 模型简洁: 采用单一Transformer架构,结构简洁,易于扩展。
● 性能优越: 在图像生成、视觉语言理解和视频生成等多个任务上,Emu3的性能超过了多个已有的特定任务模型和旗舰级模型,如SDXL和LLaVA-1.6。
● 无需预训练模型: 图像生成和视觉语言理解无需依赖预训练的CLIP和LLM。
● 支持视频生成和扩展: 能够生成高质量的视频,并能通过预测下一个token来扩展视频,预测未来的场景。
● 开源关键技术和模型: 开源了视觉标记器等关键技术和模型,方便后续研究。
>> 结论和观点:
● 下一个token预测的有效性: 论文证明了仅使用下一个token预测就能训练出在多模态任务上达到最先进性能的模型,这为构建通用的多模态智能提供了一种新的范式。
● 模型简洁性的重要性: 简化模型设计,专注于token,可以提高模型的可扩展性和训练效率。
● 多模态智能的未来方向: 下一个token预测是构建通用多模态智能的有前景的途径,这将推动人工智能领域进一步发展。
总而言之,Emu3 通过简洁的模型架构和强大的训练方法,在多模态任务上取得了突破性进展,为未来多模态模型的研究和应用提供了新的思路。 其开源的特性也为社区的进一步研究和发展提供了重要的支持。
Emu3的简介
Emu3是由BAAI(北京人工智能研究院)的Emu团队在2024年9月27日发布的一系列最先进的多模态模型。该模型的核心创新在于它仅仅使用下一个Token预测进行训练,无需依赖扩散模型或组合式架构。通过将图像、文本和视频标记到离散空间,Emu3在一个单一的Transformer模型中处理各种多模态序列。 Emu3在生成和感知任务上都表现出色,超过了SDXL、LLaVA-1.6和OpenSora-1.2等旗舰级开源模型。
总而言之,Emu3是一个很有潜力的多模态模型,其基于下一个Token预测的训练方法和单一Transformer架构非常具有创新性。 虽然项目目前尚不完整,但提供的示例代码已经展示了其强大的能力,值得关注其未来的发展。
GitHub地址:GitHub - baaivision/Emu3: Next-Token Prediction is All You Need
论文地址:https:///abs/2409.18869
1、特点
>> 基于下一个Token预测: Emu3的训练完全依赖于下一个Token预测,这与许多依赖扩散模型或其他复杂架构的多模态模型形成对比。
>> 单一Transformer架构: 使用单一的Transformer模型处理图像、文本和视频等多种模态数据,简化了模型结构。
>> 高性能: 在图像生成、视觉语言理解和视频生成等任务上,Emu3的性能超过了多个已建立的特定任务模型以及一些旗舰级开源模型。
>> 灵活的图像生成: 能够根据文本输入生成高质量的图像,自然支持灵活的分辨率和风格。
>> 强大的视觉语言理解能力: 无需依赖CLIP和预训练的LLM,就能实现强大的视觉语言理解能力。
>> 因果视频生成: 能够通过预测视频序列中的下一个Token来生成视频,不同于Sora等视频扩散模型。
>> 视频扩展预测: 在给定视频上下文的情况下,可以自然地扩展视频并预测接下来会发生什么。
2、每个模块的内容
assets: 包含示例图像和视频等资源文件。
emu3: 核心模型代码。
replicate_demo: 用于复现演示的代码。
scripts: 训练脚本 (目前仅提供部分)。
autoencode.py: 图像和视频自动编码的代码。
gradio_demo.py: Gradio演示的代码 (目前似乎缺失)。
image_generation.py: 图像生成的代码。
multimodal_understanding.py: 多模态理解的代码。
需要注意的是,该项目目前仍处于开发阶段,一些模块的代码尚未发布,例如推理代码、评估代码以及部分训练脚本。
Emu3的装和使用方法
1、克隆仓库并安装依赖
git clone https://github.com/baaivision/Emu3
cd Emu3
pip install -r requirements.txt
2、下载模型权重
Emu3 提供了多个预训练模型,包括 Emu3-Stage1(图像预训练模型)、Emu3-Chat(视觉语言理解模型)和 Emu3-Gen(图像生成模型),以及 Emu3-VisionTokenizer(视觉标记器)。这些模型的权重可以在 Hugging Face、ModelScope 和 WiseModel 上获取 (链接在GitHub页面上提供,但此处未列出具体链接)。
3、使用Hugging Face Transformers进行推理:
该项目提供了使用Hugging Face Transformers库进行推理的示例代码,分别演示了图像生成、视觉语言理解和视觉编码解码三个任务:
图像生成 (Emu3-Gen/Stage1)
代码展示了如何使用 Emu3-Gen 或 Emu3-Stage1 模型根据文本提示生成图像。 代码中使用了 Classifier Free Guidance,并支持负向提示词来控制生成结果。
from PIL import Image
from transformers import AutoTokenizer, AutoModel, AutoImageProcessor, AutoModelForCausalLM
from transformers.generation.configuration_utils import GenerationConfig
from transformers.generation import LogitsProcessorList, PrefixConstrainedLogitsProcessor, UnbatchedClassifierFreeGuidanceLogitsProcessor
import torch
from emu3.mllm.processing_emu3 import Emu3Processor
# model path
EMU_HUB = "BAAI/Emu3-Gen"
VQ_HUB = "BAAI/Emu3-VisionTokenizer"
# prepare model and processor
model = AutoModelForCausalLM.from_pretrained(
EMU_HUB,
device_map="cuda:0",
torch_dtype=torch.bfloat16,
attn_implementation="flash_attention_2",
trust_remote_code=True,
)
tokenizer = AutoTokenizer.from_pretrained(EMU_HUB, trust_remote_code=True, padding_side="left")
image_processor = AutoImageProcessor.from_pretrained(VQ_HUB, trust_remote_code=True)
image_tokenizer = AutoModel.from_pretrained(VQ_HUB, device_map="cuda:0", trust_remote_code=True).eval()
processor = Emu3Processor(image_processor, image_tokenizer, tokenizer)
# prepare input
POSITIVE_PROMPT = " masterpiece, film grained, best quality."
NEGATIVE_PROMPT = "lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry."
classifier_free_guidance = 3.0
prompt = "a portrait of young girl."
prompt += POSITIVE_PROMPT
kwargs = dict(
mode='G',
ratio="1:1",
image_area=model.config.image_area,
return_tensors="pt",
padding="longest",
)
pos_inputs = processor(text=prompt, **kwargs)
neg_inputs = processor(text=NEGATIVE_PROMPT, **kwargs)
# prepare hyper parameters
GENERATION_CONFIG = GenerationConfig(
use_cache=True,
eos_token_id=model.config.eos_token_id,
pad_token_id=model.config.pad_token_id,
max_new_tokens=40960,
do_sample=True,
top_k=2048,
)
h = pos_inputs.image_size[:, 0]
w = pos_inputs.image_size[:, 1]
constrained_fn = processor.build_prefix_constrained_fn(h, w)
logits_processor = LogitsProcessorList([
UnbatchedClassifierFreeGuidanceLogitsProcessor(
classifier_free_guidance,
model,
unconditional_ids=neg_inputs.input_ids.to("cuda:0"),
),
PrefixConstrainedLogitsProcessor(
constrained_fn ,
num_beams=1,
),
])
# generate
outputs = model.generate(
pos_inputs.input_ids.to("cuda:0"),
GENERATION_CONFIG,
logits_processor=logits_processor,
attention_mask=pos_inputs.attention_mask.to("cuda:0"),
)
mm_list = processor.decode(outputs[0])
for idx, im in enumerate(mm_list):
if not isinstance(im, Image.Image):
continue
im.save(f"result_{idx}.png")
视觉语言理解 (Emu3-Chat)
代码展示了如何使用 Emu3-Chat 模型根据图像描述图像内容。
from PIL import Image
from transformers import AutoTokenizer, AutoModel, AutoImageProcessor, AutoModelForCausalLM
from transformers.generation.configuration_utils import GenerationConfig
import torch
from emu3.mllm.processing_emu3 import Emu3Processor
# model path
EMU_HUB = "BAAI/Emu3-Chat"
VQ_HUB = "BAAI/Emu3-VisionTokenier"
# prepare model and processor
model = AutoModelForCausalLM.from_pretrained(
EMU_HUB,
device_map="cuda:0",
torch_dtype=torch.bfloat16,
attn_implementation="flash_attention_2",
trust_remote_code=True,
)
# used for Emu3-Chat
tokenizer = AutoTokenizer.from_pretrained(EMU_HUB, trust_remote_code=True, padding_side="left")
# used for Emu3-Stage1
# tokenizer = AutoTokenizer.from_pretrained(
# EMU_HUB,
# trust_remote_code=True,
# chat_template="{image_prompt}{text_prompt}",
# padding_side="left",
# )
image_processor = AutoImageProcessor.from_pretrained(VQ_HUB, trust_remote_code=True)
image_tokenizer = AutoModel.from_pretrained(VQ_HUB, device_map="cuda:0", trust_remote_code=True).eval()
processor = Emu3Processor(image_processor, image_tokenizer, tokenizer)
# prepare input
text = "Please describe the image"
image = Image.open("assets/demo.png")
inputs = processor(
text=text,
image=image,
mode='U',
return_tensors="pt",
padding="longest",
)
# prepare hyper parameters
GENERATION_CONFIG = GenerationConfig(
pad_token_id=tokenizer.pad_token_id,
bos_token_id=tokenizer.bos_token_id,
eos_token_id=tokenizer.eos_token_id,
max_new_tokens=1024,
)
# generate
outputs = model.generate(
inputs.input_ids.to("cuda:0"),
GENERATION_CONFIG,
attention_mask=inputs.attention_mask.to("cuda:0"),
)
outputs = outputs[:, inputs.input_ids.shape[-1]:]
print(processor.batch_decode(outputs, skip_special_tokens=True)[0])
视觉编码解码 (Emu3-VisionTokenizer)
代码展示了如何使用 Emu3-VisionTokenizer 模型对图像和视频进行编码和解码。 提供了图像和视频的自动编码示例。
import os
import os.path as osp
from PIL import Image
import torch
from transformers import AutoModel, AutoImageProcessor
MODEL_HUB = "BAAI/Emu3-VisionTokenizer"
model = AutoModel.from_pretrained(MODEL_HUB, trust_remote_code=True).eval().cuda()
processor = AutoImageProcessor.from_pretrained(MODEL_HUB, trust_remote_code=True)
# TODO: you need to modify the path here
VIDEO_FRAMES_PATH = "YOUR_VIDEO_FRAMES_PATH"
video = os.listdir(VIDEO_FRAMES_PATH)
video.sort()
video = [Image.open(osp.join(VIDEO_FRAMES_PATH, v)) for v in video]
images = processor(video, return_tensors="pt")["pixel_values"]
images = images.unsqueeze(0).cuda()
# image autoencode
image = images[:, 0]
print(image.shape)
with torch.no_grad():
# encode
codes = model.encode(image)
# decode
recon = model.decode(codes)
recon = recon.view(-1, *recon.shape[2:])
recon_image = processor.postprocess(recon)["pixel_values"][0]
recon_image.save("recon_image.png")
# video autoencode
images = images.view(
-1,
model.config.temporal_downsample_factor,
*images.shape[2:],
)
print(images.shape)
with torch.no_grad():
# encode
codes = model.encode(images)
# decode
recon = model.decode(codes)
recon = recon.view(-1, *recon.shape[2:])
recon_images = processor.postprocess(recon)["pixel_values"]
for idx, im in enumerate(recon_images):
im.save(f"recon_video_{idx}.png")
这些示例代码提供了详细的步骤,包括模型加载、输入预处理、超参数设置和输出后处理。 用户需要根据自己的需求修改代码中的模型路径、输入数据和超参数。
Emu3的案例应用
提供的示例代码展示了Emu3在图像生成和视觉语言理解方面的应用。 图像生成示例可以生成各种风格和分辨率的图像,视觉语言理解示例可以对图像进行准确的描述。 视频自动编码示例演示了模型处理视频数据的能力。