Diffusers documentation
Bria Fibo 2.0
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
< source >( 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__
< source >( 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
< source >( 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 会在任何待编辑图像之后看到这些图像。