# マルチモーダル生成

Multimodal (any-to-any) models are language models capable of processing diverse types of input data (e.g., text, images, audio, or video) and generating outputs in any of these modalities. Unlike traditional unimodal or fixed-modality models, they allow flexible combinations of input and output, enabling a single system to handle a wide range of tasks: from text-to-image generation to audio-to-text transcription, image captioning, video understanding, and so on. This task shares many similarities with image-text-to-text, but supports a wider range of input and output modalities.

このガイドでは、any-to-anyモデルの概要を簡潔に紹介し、Transformersを使用して推論を行う方法を説明します。ビジョンLLMは通常、ビジョンと言語のタスクに限定されますが、オムニモーダルモデルは、テキスト、画像、音声、動画などの任意のモダリティの組み合わせを入力として受け入れ、テキストや画像などの異なるモダリティで出力を生成できます。

依存関係のインストールから始めましょう。

```bash
pip install -q transformers accelerate flash_attn
```

モデルとプロセッサを初期化しましょう。

```python
from transformers import AutoProcessor, AutoModelForMultimodalLM, infer_device
import torch

device = torch.device(infer_device())
model = AutoModelForMultimodalLM.from_pretrained(
    "Qwen/Qwen2.5-Omni-3B",
    dtype=torch.bfloat16,
    attn_implementation="flash_attention_2",
).to(device)

processor = AutoProcessor.from_pretrained("Qwen/Qwen2.5-Omni-3B")
```

これらのモデルには通常、[チャットテンプレート](../chat_templating)が含まれており、モダリティをまたいだ会話の構造を定義します。入力では、1つのターン内で画像、テキスト、音声、またはその他のサポートされている形式を組み合わせることができます。出力も設定に応じて変化します（例: テキスト生成や音声生成など）。

以下は、"text + audio"を入力として提供し、テキスト応答を要求する例です。

```python
messages = [
    {
        "role": "user",
        "content": [
            {"type": "audio", "url": "https://huggingface.co/datasets/raushan-testing-hf/audio-test/resolve/main/f2641_0_throatclearing.wav"},
            {"type": "text", "text": "What do you hear in this audio?"},
        ]
    },
]
```

次に、プロセッサの [apply_chat_template()](/docs/transformers/main/ja/main_classes/processors#transformers.ProcessorMixin.apply_chat_template) メソッドを呼び出し、出力と画像入力を前処理します。

```python
inputs = processor.apply_chat_template(
    messages,
    tokenize=True,
    return_dict=True,
    return_tensors="pt",
    add_generation_prompt=True,
)
```

これで、前処理済みの入力をモデルに渡すことができます。

```python
with torch.no_grad():
    generated_ids = model.generate(**inputs, max_new_tokens=100)
generated_texts = processor.batch_decode(generated_ids, skip_special_tokens=True)
print(generated_texts)
```

## パイプライン

[Pipeline](/docs/transformers/main/ja/main_classes/pipelines#transformers.Pipeline) API を使用するのが、最も簡単な始め方です。`"any-to-any"` タスクと、使用するモデルを指定します。

```python
from transformers import pipeline
pipe = pipeline("any-to-any", model="mistralai/Voxtral-Mini-3B-2507")
```

以下の例では、テキスト入力を整形するためにチャットテンプレートを使用し、マルチモーダルデータとして音声モダリティを使用しています。

```python
messages = [
     {
         "role": "user",
         "content": [
             {
                 "type": "audio",
                 "url": "https://huggingface.co/datasets/raushan-testing-hf/audio-test/resolve/main/glass-breaking-151256.mp3",
             },
             {"type": "text", "text": "What do you hear in this audio?"},
         ],
     },
 ]
```

チャットテンプレートで整形されたテキストと画像を[Pipeline](/docs/transformers/main/ja/main_classes/pipelines#transformers.Pipeline)に渡し、`return_full_text=False`を設定して、生成された出力から入力を除去します。

```python
outputs = pipe(text=messages, max_new_tokens=20, return_full_text=False)
outputs[0]["generated_text"]
```

Any-to-any pipeline also supports generating audio or images with any-to-any models. For that you need to set `generation_mode` parameter. Do not forget to set video sampling to the desired FPS, otherwise the whole video will be loaded without sampling. Here is an example code:

```python
import soundfile as sf
pipe = pipeline("any-to-any", model="Qwen/Qwen2.5-Omni-3B")
messages = [
    {
        "role": "user",
        "content": [
            {"type": "video", "path": "https://huggingface.co/datasets/raushan-testing-hf/videos-test/resolve/main/Cooking_cake.mp4"},
            {"type": "text", "text": "Describe this video."},
        ],
    },
]
output = pipe(text=messages, fps=1, load_audio_from_video=True, max_new_tokens=20, generation_mode="audio")
sf.write("generated_audio.wav", out[0]["generated_audio"])
```

