# Bria Fibo 2.0

Fibo 2.0 は、[Bria](https://huggingface.co/briaai) による 8.1B パラメータの flow-matching transformer で、構造化された JSON キャプションから画像を生成します。そのテキストエンコーダーは [Qwen3-VL](https://huggingface.co/Qwen/Qwen3-VL-4B-Instruct) です。Perceiver が Qwen3-VL の隠れ状態を gist トークンに凝縮し、それらが画像トークンと一つのストリームで結合されます。また、transformer の 5 つのブロックは、ゲート付きクロスアテンションを通じて Qwen3-VL を直接読み取ります。

チェックポイントは2つあります:

- [`briaai/Fibo-2.0-dev`](https://huggingface.co/briaai/Fibo-2.0-dev)は、classifier-free guidance を備えたテキストから画像生成および編集を行うフルモデルです。このチェックポイント向けに、パイプラインのデフォルトは30ステップ、guidance 5 に設定されています。
- [`briaai/Fibo-2.0-edit-turbo`](https://huggingface.co/briaai/Fibo-2.0-edit-turbo)は、ガイダンスなし（`guidance_scale=1.0`）で4ステップの編集を行うために蒸留されたモデルです。

guidance on の場合、デフォルトの negative prompt は、モデルが学習時に使用した null caption であり、すべての値が空欄に設定された構造化キャプションです。

## 生成

Fibo 2.0 は構造化された JSON キャプションで学習されており、自由形式のテキストではうまく動作しません。キャプションを JSON 文字列として渡してください:

```py
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`フィールドを削除し、キャプションをコンパクトにシリアライズします。また、2つの短い形式もトレーニングされており、そのまま保持されます。

```py
# 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](https://huggingface.co/briaai/FIBO)ページのprompt-to-JSONモデルを参照してください。

## 編集

同じパイプラインで画像を編集できます。画像を`image`として、編集指示をプロンプトとして渡します:

```py
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 を無効にします:

```py
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`を前提として進みます。ターボチェックポイントを使用する場合は、各呼び出しに`num_inference_steps=4`と`guidance_scale=1.0`を渡してください。

### 編集プロンプト

プロンプトは、`"edit_instruction"`キーと結果のキャプションを含むJSONオブジェクトとしても指定できます。この場合、キャプションはFibo 2.0が編集用に学習した形式のいずれかである必要があります。パイプラインは、これをFibo 2.0が編集用に学習した形式のプロンプトに変換します。

完全なキャプション: `"edit_instruction"` 以外のキャプションのキーは、Bria のプロンプトから JSON へのモデルが編集用に書き出す形式です。パイプラインは空の値と、トレーニングで全キャプションから削除された `aesthetic_score` および `preference_score` フィールドを除外します。

```py
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"` キー内の文字列。

```py
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"`キーには、この形式のデータや、完全なキャプションを格納することもできます。

```py
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枚の画像を同時に編集でき、例えば1枚の画像にあるオブジェクトを別の画像に配置することができます。指示では、`<image_1>`、`<image_2>` のように、画像を順番に参照します。

```py
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 が学習されたサイズ（約 1 メガピクセル）になります。1 枚の画像は結果のサイズにクロップされます。複数の画像は、それぞれ自身のアスペクト比に対する学習サイズにクロップされます。

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

### マスク付き編集

`mask` は、再生成する単一の画像の領域を、画像サイズで白黒（白が対象領域）で示します。Fibo 2.0 は、その領域がグレーアウトされた画像の編集で学習されており、パイプラインも画像をエンコードする前に同じ方法でグレーアウトします。具体的には、128 でバイナリ化されたマスクを介して、フラットな (128, 128, 128) のグレーを適用します。

```py
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`エントリ内でテキストを要求する場合、Fibo 2.0 は、Qwen3-VL が各テキストを個別に描画された状態で確認できる場合に、より適切にレンダリングする傾向があります。このパイプラインは、トレーニング時と同様にこれらの画像をデフォルトで描画しますが、無効にすることもできます。テキストを含むキャプション（上記のベーカリーの例など）の場合：

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

トレーニングでは、テキスト付きのキャプションに対してはこれらの画像をFibo 2.0に提示し、そうでないキャプションに対しては提示しなかったため、どちらの場合でも動作します。

- `text` を持つ各 `text_render` エントリには画像が割り当てられます。テキストは1行で、白地に黒字、Pillow の組み込みフォントのサイズ 20 で表示されます。256 文字を超えるテキストは、256 文字ごとに改行されます。
- フォントにない文字は、`fonts` のうち最初にその文字を含むフォントで描画されます。トレーニングでは Aileron、次に DejaVu Sans が使用されており、これらは [`briaai/Fibo-2.0-dev`](https://huggingface.co/briaai/Fibo-2.0-dev) の `fonts` フォルダにあります。`fonts` が存在しない場合、そのような文字は Pillow の組み込みフォントで描画され、パイプラインから警告が表示されます。
- パイプラインは、各エントリにその画像用の`image_tokens`フィールドを付与し、Qwen3-VLは編集対象の画像の後に画像を確認します。
- 生成は、ノイズレベルが`pipe.text_images_max_noise_level`(0.9)を超える間、最初のステップを画像なしのキャプションに対して実行します。一方、編集はすべてのステップでそれらを使用します。
- テキストのないキャプションでは画像が生成されず、トレーニングと同様に短い説明でも同様です。

学習で使用したフォントでそれらを描画するには:

```py
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` を持つ各 `text_render` エントリに、`text_images` として1枚ずつ順番に渡します。これらは、パイプライン自体が生成する画像よりも優先されます。学習時と異なる方法で描画された画像は、分布外となります。

## アテンションのバックエンド

transformer は、diffusers の [attention バックエンド](../../optimization/attention_backends) のいずれでも実行できます。例えば、H100 などの Hopper GPU では FlashAttention-3 が使用できます:

```py
pipe.transformer.set_attention_backend("_flash_3_varlen_hub")
```

`_flash_3_hub` は単一のプロンプトにも対応しますが、マスクを受け取らないため、長さの異なるプロンプトのバッチ処理は実行できません（後述）。

## バッチ処理

1回の呼び出しで複数のプロンプトを生成できます。長さの異なるプロンプトはパディングされ、そのパディングはすべてのアテンション層でマスクされます。そのため、このようなバッチにはマスクを扱うアテンションバックエンドが必要です。デフォルトのバックエンド、または`flash_varlen`のようなvarlenバックエンドが該当します。float32では、バッチ処理は個別呼び出しの画像を再現しますが、bfloat16ではパディングありとパディングなしの入力間でアテンションカーネルが異なるため、バッチ処理の画像は個別呼び出しと細部の点で異なる場合があります。

## BriaFibo2Pipeline[[diffusers.BriaFibo2Pipeline]]

#### diffusers.BriaFibo2Pipeline[[diffusers.BriaFibo2Pipeline]]

```python
diffusers.BriaFibo2Pipeline(transformer: BriaFibo2Transformer2DModel, scheduler: FlowMatchEulerDiscreteScheduler, vae: AutoencoderKLFlux2, text_encoder: Qwen3VLForConditionalGeneration, processor: Qwen3VLProcessor)
```

[ソース](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/bria_fibo2/pipeline_bria_fibo2.py#L171)

**パラメータ:**

transformer ([BriaFibo2Transformer2DModel](/docs/diffusers/v0.43.0/ja/api/models/transformer_bria_fibo2#diffusers.BriaFibo2Transformer2DModel)) : 画像の潜在変数をノイズ除去する Transformer。

scheduler ([FlowMatchEulerDiscreteScheduler](/docs/diffusers/v0.43.0/ja/api/schedulers/flow_match_euler_discrete#diffusers.FlowMatchEulerDiscreteScheduler)) : `transformer`と組み合わせて、潜在変数のノイズ除去に使用されるスケジューラー。

vae (`AutoencoderKLFlux2`) : 画像を潜在変数に、また潜在変数を画像にマッピングする変分オートエンコーダーです。

text_encoder (`Qwen3VLForConditionalGeneration`) : Qwen3-VL。その隠れ状態が transformer を条件付けます。

processor (`Qwen3VLProcessor`) : プロンプトと編集対象の画像を Qwen3-VL の入力に変換します。

Fibo 2.0によるテキストから画像への生成および画像編集のためのPipeline。

#### __call__[[diffusers.BriaFibo2Pipeline.__call__]]

```python
__call__(prompt: str | list[str] | None = None, image: PIL.Image.Image | list[PIL.Image.Image] | None = None, mask: PIL.Image.Image | None = None, text_images: list[PIL.Image.Image] | None = None, render_text_images: bool = True, fonts: list[str] | None = None, height: int | None = None, width: int | None = None, num_inference_steps: int = 30, guidance_scale: float = 5.0, negative_prompt: str | list[str] | None = None, num_images_per_prompt: int = 1, generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = None, latents: typing.Optional[torch.Tensor] = None, prompt_embeds: typing.Optional[torch.Tensor] = None, prompt_embeds_mask: typing.Optional[torch.Tensor] = None, negative_prompt_embeds: typing.Optional[torch.Tensor] = None, negative_prompt_embeds_mask: typing.Optional[torch.Tensor] = None, output_type: str = 'pil', return_dict: bool = True, callback_on_step_end: typing.Optional[typing.Callable[[int, int, dict], NoneType]] = None, callback_on_step_end_tensor_inputs: list[str] = ['latents'])
```

[ソース](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/bria_fibo2/pipeline_bria_fibo2.py#L571)

**パラメータ:**

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]`、*任意*) : 編集対象の画像、または指示で `<image_1>`、`<image_2>` などとして参照できる最大 5 枚の画像。`image` を指定しない場合、パイプラインはプロンプトから画像を生成します。

mask (`PIL.Image.Image`, *任意*) : 単一の画像を編集する場合、`image`を再生成する領域を、黒地に白で示したものです。学習時と同様に、マスクを128で二値化して作成したマスクにより、画像をエンコードする前に領域をグレーアウトします。

text_images (`list[PIL.Image.Image]`, *任意*) : キャプションが要求するテキストの画像を、`text` を持つ `text_render` エントリごとに 1 枚ずつ、順序どおりに保持します。各エントリのテキストは、`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`) : 各キャプションの`text_images`を、Fibo 2.0 の学習時に描画した方法で描画するかどうかを指定します。具体的には、各テキストを1行ずつ、白地に黒文字で、Pillow の組み込みフォントのサイズ 20 で描画し、そのフォントにない文字は、それを含む`fonts`の先頭にあるフォントで描画します。テキストのないキャプションや、JSON キャプションのないプロンプト（短い説明など）は、学習時と同様に画像が生成されません。

fonts (`list[str]`、*任意*) : `text_images` の文字のうち、Pillow の組み込みフォントにないものを描画するためのフォントのパスを、使用順に指定します。学習時には、`briaai/Fibo-2.0-dev` の `fonts` フォルダにある Aileron、次に DejaVu Sans の順で描画されていました。これらを指定しない場合、そのような文字は Pillow の組み込みフォントで描画されます。

height (`int`, *optional*) : 生成される画像のピクセル単位の縦幅。16で割り切れる必要があります。デフォルトは1024です。編集を行う場合は、最初の画像のアスペクト比に対してFibo 2.0が学習されたサイズ（約1メガピクセル）になります。

width (`int`、*任意*) : 生成される画像の幅（ピクセル単位）。16で割り切れる必要があります。`height`と同様にデフォルト値が設定されています。

num_inference_steps (`int`、*任意*、デフォルトは 30) : デノイジングのステップ数。

guidance_scale (`float`、*任意*、デフォルト値は 5.0) : Classifier-free guidance のスケールです。1 より大きい値の場合、各ステップでネガティブプロンプトを第 2 パスとして実行し、1.0 にすると guidance が無効になります。

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`, *任意*) : `prompt_embeds` と一緒に `encode_prompt` が返すマスクです。パディングがある場合に必要です。

negative_prompt_embeds (`torch.Tensor`, *任意*) : `negative_prompt`の代わりに使用される、ネガティブプロンプトの事前計算済みテキスト埋め込み。

negative_prompt_embeds_mask (`torch.Tensor`, *任意*) : `negative_prompt_embeds` と一緒に `encode_prompt` が返すマスクです。パディングがある場合に必要です。

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`

生成された画像。

生成用のパイプラインを呼び出したときに実行される関数。

例:
```py
>>> 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[[diffusers.BriaFibo2Pipeline.encode_prompt]]

```python
encode_prompt(prompt: str | list[str], image: list[PIL.Image.Image] | None = None, device: typing.Optional[torch.device] = None, num_images_per_prompt: int = 1, prompt_embeds: typing.Optional[torch.Tensor] = None, prompt_embeds_mask: typing.Optional[torch.Tensor] = None, text_images: list[PIL.Image.Image] | list[list[PIL.Image.Image]] | None = None)
```

[ソース](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/bria_fibo2/pipeline_bria_fibo2.py#L351)

**パラメータ:**

prompt (`str` または `list[str]`) : エンコードするプロンプトまたはプロンプトのリストです。`image` を使用する場合、各プロンプトは編集指示、または `"edit_instruction"` キーと結果のキャプションを持つ JSON オブジェクトです。その他のキー、またはキャプションや短い説明を保持する `"structured_caption"` キーです。生成プロンプトは与えられたままエンコードされます。`__call__` は、まず Fibo 2.0 の学習時に使用された形式の JSON キャプションを挿入します。

image (`list[PIL.Image.Image]`, *optional*) : Qwen3-VL が認識する形式の編集対象画像です。すべてのプロンプトがこれらすべての画像に適用されます。

device (`torch.device`、*optional*) : 埋め込みを配置するデバイス。

num_images_per_prompt (`int`、デフォルトは 1) : プロンプトごとに生成する画像の数。

prompt_embeds (`torch.Tensor`, *任意*) : `prompt` の代わりに使用される、形状が `(batch_size, 6, text_len, 7680)` の事前計算済みテキスト埋め込み。

prompt_embeds_mask (`torch.Tensor`, *任意*) : `prompt_embeds` 内の実際のトークンの Bool マスク。形状は `(batch_size, text_len)` です。

text_images (`list[PIL.Image.Image]` または `list[list[PIL.Image.Image]]`、*任意*) : キャプションのテキストに対応する画像で、`text` を持つ `text_render` エントリごとに 1 枚ずつ、順序どおり配置します。プロンプトごとにそれらのリストを指定することもできます。各エントリにはその画像のビジョンマーカーが割り当てられ、Qwen3-VL は編集対象の画像の後にこれらの画像を確認します。

**戻り値:**

テキスト埋め込み、およびそのマスク、またはプロンプトがパディングされていない場合は`None`。

