Diffusers documentation

Bria Fibo 2.0

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.42.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Bria Fibo 2.0

Fibo 2.0 是由 Bria 推出的 8.1B 参数流匹配 Transformer,可根据结构化的 JSON 描述生成图像。其文本编码器为 Qwen3-VL:Perceiver 将 Qwen3-VL 的隐藏状态压缩为摘要 token,使其与图像 token 合并到同一流中;此外,Transformer 中的五个块还通过门控交叉注意力机制直接读取 Qwen3-VL。

有两个检查点:

  • briaai/Fibo-2.0-dev,用于文本生成图像和编辑的完整模型,支持 classifier-free guidance。该流水线的默认设置(30 步,guidance 为 5)适用于此 checkpoint。
  • briaai/Fibo-2.0-edit-turbo,经过蒸馏,可在无引导(guidance_scale=1.0)的情况下以 4 步完成编辑。

在开启 guidance 的情况下,默认的 negative prompt 是模型训练时使用的空描述:即所有值均留空的结构化描述。

生成

Fibo 2.0 基于结构化 JSON 描述进行训练,因此无法很好地处理自由文本。请将描述作为 JSON 字符串传入:

import json

import torch
from diffusers import BriaFibo2Pipeline

pipe = BriaFibo2Pipeline.from_pretrained("briaai/Fibo-2.0-dev", dtype=torch.bfloat16).to("cuda")

caption = {
    "short_description": "A red vintage bicycle leaning against a whitewashed wall on a narrow Mediterranean street.",
    "objects": [
        {
            "description": "A red vintage bicycle with a wicker basket of lemons on its handlebars.",
            "location": "center",
            "relative_size": "large within frame",
        }
    ],
    "background_setting": "A whitewashed wall with a blue wooden door and potted red geraniums.",
    "lighting": {"conditions": "bright morning sun", "direction": "from the right", "shadows": "long and crisp"},
    "aesthetics": {"composition": "centered", "color_scheme": "red, white and blue", "mood_atmosphere": "calm"},
    "photographic_characteristics": {"depth_of_field": "deep", "focus": "sharp on the bicycle", "camera_angle": "eye level"},
    "style_medium": "photograph",
    "context": "A travel photograph.",
    "artistic_style": "realistic",
}
image = pipe(json.dumps(caption)).images[0]
image.save("bicycle.png")

该流水线以与训练相同的方式清理字幕:它会丢弃空值以及 aesthetic_score 和 preference_score 字段(训练字幕中均不包含这些字段),并以紧凑格式序列化字幕。此外,还训练了两种简短形式,并原样保留:

# The caption's short description alone, as plain text
image = pipe("A red vintage bicycle leaning against a whitewashed wall on a narrow Mediterranean street.").images[0]

# Exactly a "short_description" and a "text_render" list. The list is kept even when it's empty, to say the image
# has no text
caption = {"short_description": "A bakery storefront at dawn with a painted sign.", "text_render": [{"text": "FRESH BREAD"}]}
image = pipe(json.dumps(caption)).images[0]

要将自由文本转换为结构化字幕,请参阅 Bria Fibo 页面上的 prompt-to-JSON 模型。

编辑

相同的流水线用于编辑图像。将图像作为 image 传入,并将编辑指令作为提示词:

import torch
from diffusers import BriaFibo2Pipeline
from diffusers.utils import load_image

pipe = BriaFibo2Pipeline.from_pretrained("briaai/Fibo-2.0-dev", dtype=torch.bfloat16).to("cuda")
image = load_image(
    "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/yarn-art-pikachu.png"
)
edited = pipe("Make the background a snowy forest", image=image).images[0]
edited.save("pikachu_snow.png")

为了更快地进行编辑,请加载 turbo 检查点并关闭 guidance:

import torch
from diffusers import BriaFibo2Pipeline
from diffusers.utils import load_image

pipe = BriaFibo2Pipeline.from_pretrained("briaai/Fibo-2.0-edit-turbo", dtype=torch.bfloat16).to("cuda")
image = load_image(
    "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/yarn-art-pikachu.png"
)
edited = pipe("Make the background a snowy forest", image=image, num_inference_steps=4, guidance_scale=1.0).images[0]
edited.save("pikachu_snow.png")

以下示例基于其中任意一个继续,使用其 pipe 和 image。对于 turbo 检查点,请在每次调用时传入 num_inference_steps=4 和 guidance_scale=1.0。

编辑提示

提示词也可以是一个 JSON 对象,其中包含 "edit_instruction" 键以及结果的描述,其形式可以是 Fibo 2.0 训练时所采用的任意一种编辑形式。该流水线会将其转换为 Fibo 2.0 训练时所采用的编辑提示词。

完整说明:说明中位于 "edit_instruction" 旁边的键,与 Bria 的 prompt-to-JSON 模型为编辑所生成的格式一致。该流水线会丢弃空值以及 aesthetic_score 和 preference_score 字段,因为训练已从所有说明中移除了这些字段。

import json

prompt = {
    "short_description": "A crocheted yellow Pikachu doll sitting in a snowy pine forest.",
    "objects": [{"description": "A crocheted yellow Pikachu doll with red cheeks.", "location": "center"}],
    "background_setting": "A snowy pine forest with falling snow.",
    "edit_instruction": "Make the background a snowy forest",
}
edited = pipe(json.dumps(prompt), image=image).images[0]

简短描述:"structured_caption" 键中的一个字符串。

prompt = {
    "structured_caption": "A crocheted yellow Pikachu doll sitting in a snowy pine forest.",
    "edit_instruction": "Make the background a snowy forest",
}
edited = pipe(json.dumps(prompt), image=image).images[0]

简短描述及其文本:恰好是一个 "short_description" 和一个 "text_render" 列表。即使列表为空也会保留,这表示 Fibo 2.0 的结果没有文本。"structured_caption" 键可以包含此格式,也可以包含完整的说明。

prompt = {
    "short_description": "A crocheted yellow Pikachu doll holding a small wooden sign.",
    "text_render": [{"text": "HELLO"}],
    "edit_instruction": "Give the doll a small wooden sign that reads HELLO",
}
edited = pipe(json.dumps(prompt), image=image).images[0]

多张图片

最多可以同时编辑 5 张图片,例如将一张图片中的对象放入另一张图片中。指令会按顺序将它们称为 <image_1>、<image_2>,依此类推。

cat = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/cat.png")
edited = pipe("Put the cat from <image_2> next to the doll in <image_1>", image=[image, cat]).images[0]

输出大小

除非指定了 height 和 width,否则结果将采用 Fibo 2.0 针对第一张图像的宽高比进行训练时的尺寸,大约为一百万像素。单张图像会被裁剪至结果尺寸。多张图像则各自根据其自身的宽高比裁剪至训练尺寸。

edited = pipe("Make the background a snowy forest", image=image, width=1424, height=800).images[0]

掩码编辑

mask 标记了单张图像中需要重新生成的区域,以白底黑图的形式呈现,尺寸与图像一致。Fibo 2.0 是在那些将图像中该区域置灰的编辑数据上训练的,并且该流水线在图像编码前会以相同方式将其置灰:通过阈值设为 128 的二值化掩码,填充为均匀的 (128, 128, 128) 灰色。

from PIL import Image, ImageDraw

mask = Image.new("L", image.size, 0)
ImageDraw.Draw(mask).rectangle((image.width // 2, 0, image.width, image.height // 2), fill=255)
edited = pipe("Add a red balloon floating in the sky", image=image, mask=mask).images[0]

图像中的文本

当字幕中的 text_render 条目要求渲染文本时,如果 Qwen3-VL 也能看到每个单独绘制的文本,Fibo 2.0 通常能更好地渲染这些文本。该流水线默认会绘制这些图像,与训练时的做法一致,并且可以将其关闭。对于包含文本的字幕,例如上面面包店的例子:

prompt = json.dumps(caption)
image = pipe(prompt, render_text_images=False).images[0]

训练过程中,Fibo 2.0 针对部分包含文本的说明展示了这些图像,而针对其他说明则没有展示,因此两种方式均可行。

  • 每个包含 text 的 text_render 条目都会生成一张图像:文本以单行形式显示,白底黑字,使用 Pillow 内置字体,字号为 20。长度超过 256 个字符的文本会被拆分为每行 256 个字符的多行。
  • 字体中缺失的字符会使用 fonts 中第一个包含该字符的字体来绘制。训练时使用了 Aileron,然后是 DejaVu Sans,它们位于 briaai/Fibo-2.0-dev 的 fonts 文件夹中。如果没有 fonts,此类字符将按照 Pillow 内置字体的方式绘制,并且流水线会发出警告。
  • Pipeline 会为每个条目标记一个 image_tokens 字段以对应其图像,而 Qwen3-VL 会在任何待编辑图像之后看到这些图像。
  • 在生成过程中,当噪声水平高于 pipe.text_images_max_noise_level(0.9)时,前几步仅基于不含图像的文本描述进行;而在编辑过程中,每一步都会使用这些图像。
  • 没有文本的标题不会生成图像,简短的描述也不会,这与训练阶段的情况相同。

要使用训练所用的字体绘制它们:

from huggingface_hub import hf_hub_download

fonts = [
    hf_hub_download("briaai/Fibo-2.0-dev", name, subfolder="fonts")
    for name in ("Aileron-Regular.otf", "DejaVuSans.ttf")
]
image = pipe(prompt, fonts=fonts).images[0]

若要自行绘制图像,请按顺序将图像作为 text_images 传入,每个包含 text 的 text_render 条目对应一张图像,且针对单个提示词。这些图像会覆盖流水线自身生成的图像。与训练时绘制方式不同的图像属于分布外数据。

注意力后端

transformer 可运行于 diffusers 的任意注意力后端,例如在 H100 等 Hopper GPU 上使用 FlashAttention-3:

pipe.transformer.set_attention_backend("_flash_3_varlen_hub")

_flash_3_hub 同样适用于单个提示,但它不支持掩码,因此无法处理长度不同的提示批次(详见下文)。

批处理

可以在一次调用中生成多个提示。不同长度的提示会被填充(padding),并且填充部分会在每个注意力层中被掩码(mask)掉,因此这样的批次需要一个支持掩码的注意力后端:默认后端,或 flash_varlen 等变长(varlen)后端。在 float32 下,批次生成的图像与单独调用生成的图像一致;而在 bfloat16 下,填充输入与未填充输入的注意力内核存在差异,因此批次生成的图像在细节上可能与单独调用生成的图像有所不同。

BriaFibo2Pipeline

class diffusers.BriaFibo2Pipeline

< >

( transformer: BriaFibo2Transformer2DModelscheduler: FlowMatchEulerDiscreteSchedulervae: AutoencoderKLFlux2text_encoder: Qwen3VLForConditionalGenerationprocessor: Qwen3VLProcessor )

参数

  • transformer (BriaFibo2Transformer2DModel) — 用于对图像潜在表示进行去噪的 transformer。
  • scheduler (FlowMatchEulerDiscreteScheduler) — 与 transformer 配合使用,用于对潜变量进行去噪的调度器。
  • vae (AutoencoderKLFlux2) — 变分自编码器,用于将图像映射到潜在空间并还原。
  • text_encoder (Qwen3VLForConditionalGeneration) — Qwen3-VL。其隐藏状态用于条件化 transformer。
  • processor (Qwen3VLProcessor) — 将提示词和待编辑的图像转换为 Qwen3-VL 的输入。

用于使用 Fibo 2.0 进行文本生成图像和图像编辑的 Pipeline。

__call__

< >

( prompt: str | list[str] | None = Noneimage: PIL.Image.Image | list[PIL.Image.Image] | None = Nonemask: PIL.Image.Image | None = Nonetext_images: list[PIL.Image.Image] | None = Nonerender_text_images: bool = Truefonts: list[str] | None = Noneheight: int | None = Nonewidth: int | None = Nonenum_inference_steps: int = 30guidance_scale: float = 5.0negative_prompt: str | list[str] | None = Nonenum_images_per_prompt: int = 1generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = Nonelatents: typing.Optional[torch.Tensor] = Noneprompt_embeds: typing.Optional[torch.Tensor] = Noneprompt_embeds_mask: typing.Optional[torch.Tensor] = Nonenegative_prompt_embeds: typing.Optional[torch.Tensor] = Nonenegative_prompt_embeds_mask: typing.Optional[torch.Tensor] = Noneoutput_type: str = 'pil'return_dict: bool = Truecallback_on_step_end: typing.Optional[typing.Callable[[int, int, dict], NoneType]] = Nonecallback_on_step_end_tensor_inputs: list = ['latents'] ) → BriaFibo2PipelineOutput or tuple

参数

  • prompt (str 或 list[str],可选) — 用于引导图像生成的提示词,通常为结构化的 JSON 提示词。该提示词会按照 Fibo 2.0 训练时清洗字幕的方式进行处理:移除空值以及 aesthetic_score 和 preference_score 字段,并以紧凑格式进行序列化。若与 image 一起使用,则可以是编辑指令,或是一个包含 "edit_instruction" 键以及结果字幕的 JSON 对象:其其他键,或是一个包含字幕或简短描述的 "structured_caption" 键。
  • image (PIL.Image.Image 或 list[PIL.Image.Image],可选) — 要编辑的图像,或最多 5 张要一起编辑的图像,指令中可以用 <image_1>、<image_2> 等来引用它们。如果不提供 image,流水线将根据提示词生成图像。
  • mask (PIL.Image.Image,可选) — 在编辑单张图像时,指定image中需要重新生成的区域,以黑底白图表示。与训练过程相同,在图像编码之前,该区域会通过将掩码二值化(阈值为 128)而变灰。
  • text_images (list[PIL.Image.Image], 可选) — 字幕中要求渲染的文本对应的图像,按顺序对应每个包含 text 的 text_render 条目:每个条目的文本单独绘制,绘制方式与 render_text_images 相同。Qwen3-VL 会结合提示词查看这些图像,每个图像都在其对应的字幕条目中标记,这有助于 Fibo 2.0 渲染文本。需要 prompt 为单个 JSON 字幕,并且优先级高于 render_text_images。在生成过程中,当噪声水平高于 text_images_max_noise_level(0.9)时,前几步不使用这些图像;而在编辑过程中,每一步都会使用它们。
  • render_text_images (bool,可选,默认为 True) — 是否按照 Fibo 2.0 训练时的方式绘制每个 caption 的 text_images:每段文本占一行,白底黑字,使用 Pillow 内置字体,字号为 20;对于该字体缺失的字符,则使用 fonts 中第一个包含这些字符的字体。与训练时一致,没有文本的 caption,以及没有 JSON caption 的 prompt(例如简短描述),不会生成图像。
  • fonts (list[str], 可选) — 按顺序指定用于绘制 text_images 中 Pillow 内置字体所缺失字符的字体文件路径。 训练时依次使用了 Aileron 和 DejaVu Sans 字体,它们位于 briaai/Fibo-2.0-dev 的 fonts 文件夹中。如果未提供这些字体,此类字符将按 Pillow 内置字体的方式绘制。
  • height (int, 可选) — 生成图像的高度(以像素为单位)。必须能被 16 整除。默认值为 1024;在编辑模式下,默认值为 Fibo 2.0 针对第一张图像的宽高比进行训练时的尺寸,约为 100 万像素。
  • width (int, 可选) — 生成图像的宽度(以像素为单位)。必须能被 16 整除。默认值与 height 相同。
  • num_inference_steps (int,可选,默认为 30) — 去噪步数。
  • guidance_scale (float, 可选,默认值为 5.0) — 无分类器引导(Classifier-free guidance)的缩放系数。大于 1 的值会在每一步中额外运行一次负向提示词,而 1.0 则会关闭引导。
  • negative_prompt (str 或 list[str],可选) — 在启用引导时,用于引导模型远离的提示。默认值为 Fibo 2.0 训练时使用的空标题:一个所有值均为空的结构化标题。
  • num_images_per_prompt (int,可选,默认为 1) — 每个提示词生成的图像数量。
  • generator (torch.Generator 或 list[torch.Generator],可选) — 用于绘制起始噪声的生成器,以实现确定性生成。
  • latents (torch.Tensor, 可选) — 预生成的起始噪声,形状为 (batch_size, 32, height // 8, width // 8)。
  • prompt_embeds (torch.Tensor, 可选) — 来自 encode_prompt 的预计算文本嵌入,用于替代 prompt。
  • prompt_embeds_mask (torch.Tensor, 可选) — encode_prompt 与 prompt_embeds 一起返回的掩码。当存在填充时需要使用。
  • negative_prompt_embeds (torch.Tensor,可选) — 负提示的预计算文本嵌入,用于替代 negative_prompt。
  • negative_prompt_embeds_mask (torch.Tensor, 可选) — encode_prompt 与 negative_prompt_embeds 一起返回的掩码。当存在填充时需要使用。
  • output_type (str,可选,默认为 "pil") — 输出格式:"pil"、"np"、"pt" 或 "latent"。
  • return_dict (bool,可选,默认为 True) — 是否返回 BriaFibo2PipelineOutput 而不是普通元组。
  • callback_on_step_end (Callable, 可选) — 在每个去噪步骤结束时调用的函数,形式为 callback_on_step_end(self, step, timestep, callback_kwargs)。
  • callback_on_step_end_tensor_inputs(list[str],可选,默认为 ["latents"])— 传递给 callback_kwargs 中 callback_on_step_end 的张量。

返回值

BriaFibo2PipelineOutput 或 tuple

生成的图像。

调用生成 pipeline 时调用的函数。

示例:

>>> import json

>>> import torch
>>> from diffusers import BriaFibo2Pipeline
>>> from diffusers.utils import load_image

>>> # Fibo 2.0 reads structured JSON captions, serialized compactly the way it was trained
>>> caption = {
...     "short_description": "A red bicycle leaning against a white brick wall on a sunny morning.",
...     "objects": [{"description": "a red city bicycle with a wicker basket", "location": "center"}],
...     "background_setting": "a white brick wall with a green door",
...     "lighting": {"conditions": "bright morning sun", "direction": "from the right"},
...     "style_medium": "photograph",
... }
>>> prompt = json.dumps(caption, separators=(",", ":"), ensure_ascii=False)

>>> # 30 steps with guidance 5, the defaults
>>> pipe = BriaFibo2Pipeline.from_pretrained("briaai/Fibo-2.0-dev", dtype=torch.bfloat16).to("cuda")
>>> image = pipe(prompt).images[0]
>>> image.save("fibo2.png")

>>> # editing: pass the image, and the instruction as the prompt
>>> image = load_image(
...     "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/yarn-art-pikachu.png"
... )
>>> edited = pipe("Make the background a snowy forest", image=image).images[0]
>>> edited.save("fibo2_edit.png")

encode_prompt

< >

( prompt: str | list[str]image: list[PIL.Image.Image] | None = Nonedevice: typing.Optional[torch.device] = Nonenum_images_per_prompt: int = 1prompt_embeds: typing.Optional[torch.Tensor] = Noneprompt_embeds_mask: typing.Optional[torch.Tensor] = Nonetext_images: list[PIL.Image.Image] | list[list[PIL.Image.Image]] | None = None )

参数

  • prompt (str 或 list[str]) — 要编码的提示词或提示词列表。当使用 image 时,每个提示词都是一条编辑指令,或者是一个 JSON 对象,其中包含 "edit_instruction" 键以及结果的说明:其其他键,或者一个 "structured_caption" 键,其中包含说明或简短描述。生成提示词将按原样进行编码:__call__ 首先会放入一个 JSON 格式的说明,该格式与 Fibo 2.0 训练时使用的格式一致。
  • image (list[PIL.Image.Image], 可选) — 要编辑的图像,即 Qwen3-VL 所看到的图像。每个提示词都会编辑所有这些图像。
  • device (torch.device,可选) — 用于放置嵌入的设备。
  • num_images_per_prompt (int,默认为 1) — 每个提示词生成的图像数量。
  • prompt_embeds (torch.Tensor, 可选) — 形状为 (batch_size, 6, text_len, 7680) 的预计算文本嵌入,用于替代 prompt。
  • prompt_embeds_mask (torch.Tensor, 可选) — prompt_embeds 中真实 token 的布尔掩码,形状为 (batch_size, text_len)。
  • text_images (list[PIL.Image.Image] 或 list[list[PIL.Image.Image]],可选) — 字幕文本的图像,按顺序对应每个包含 text 的 text_render 条目,或者每个提示词对应一个列表。每个条目都会获得其图像的视觉标记,并且 Qwen3-VL 会在任何待编辑图像之后看到这些图像。
Update on GitHub