Buckets:

mishig's picture
|
download
raw
26.6 kB

Bria Fibo 2.0

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

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

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

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

生成

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

# 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を前提として進みます。ターボチェックポイントを使用する場合は、各呼び出しに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 フィールドを除外します。

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枚の画像を同時に編集でき、例えば1枚の画像にあるオブジェクトを別の画像に配置することができます。指示では、<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 が学習されたサイズ(約 1 メガピクセル)になります。1 枚の画像は結果のサイズにクロップされます。複数の画像は、それぞれ自身のアスペクト比に対する学習サイズにクロップされます。

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

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 の fonts フォルダにあります。fonts が存在しない場合、そのような文字は Pillow の組み込みフォントで描画され、パイプラインから警告が表示されます。
  • パイプラインは、各エントリにその画像用の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 を持つ各 text_render エントリに、text_images として1枚ずつ順番に渡します。これらは、パイプライン自体が生成する画像よりも優先されます。学習時と異なる方法で描画された画像は、分布外となります。

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

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

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]]

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

ソース

パラメータ:

transformer (BriaFibo2Transformer2DModel) : 画像の潜在変数をノイズ除去する Transformer。

scheduler (FlowMatchEulerDiscreteScheduler) : transformerと組み合わせて、潜在変数のノイズ除去に使用されるスケジューラー。

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

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

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

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

call[[diffusers.BriaFibo2Pipeline.call]]

__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'])

ソース

パラメータ:

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

生成された画像。

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

例:

>>> 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]]

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)

ソース

パラメータ:

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。

Xet Storage Details

Size:
26.6 kB
·
Xet hash:
55b27c83afdcfe090d206b1386cac01ed1b8ec82101b3e2eeca2a9843c4d2fdc

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.