生成AIを用いた画像解析による楽曲自動生成

背景

生成AIは単体での利用だけでなく、複数モデルを組み合わせて弱点を補い合うワークフロー設計によって価値が高まると考えた。その中で、雰囲気に強く依存するLo-Fi音楽を対象に、ローカル環境での生成AI運用・画像から音楽への発想拡張・モデル特性の理解を目的として構築を行なった。
※この内容は趣味範囲のものであり、学校などの研究として取り組んだものではないことをここに記す。

使用したツール

生成AIモデルStable Diffusion
MusicGen
BLIP
主要ライブラリDiffusers
Audiocraft
Transformers
Torch / Torchvision / Torchaudio
プログラミング言語Python
実行環境OS: Windows 11
CPU: Ryzen 7 8700G
GPU: GeForce RTX 3060 (12GB)

結果

結果1

生成された画像

プロンプト: 「cafe at rainy night, neon city lights reflected in window, cozy interior, warm indoor lamps, 90s retro style, melancholic but warm」

Stable Diffusionで生成された画像1

生成された音楽

結果2

生成された画像

プロンプト: 「lofi cafe, golden hour sunset, dust motes dancing in light, cluttered bookshelves, anime style, cinematic composition, warm orange tones」

Stable Diffusionで生成された画像2

生成された音楽

  • 画像の雰囲気を反映したLo-Fi音楽を生成できた
  • ローカル環境で生成AIモデルを実行できることを体感できた
  • 画像の違いが、どのように音楽に反映されるかを認識できた

学んだこと

ローカル環境にて、どのようにしてAIを動かすことができるのかを学習することができた。また、生成AIはワークフロー設計が重要だということが分かった。当初、すべての作業を1つの仮想環境で行おうとしていたが依存関係の解消が難しく、今回は2つの仮想環境に分けてモデルを実行することとした。また、入力の抽象度が結果品質に大きく影響するため、モデルの特性を理解しながら、どういった組み合わせで実行するかを検証しながらフロー設計が必要だと感じた。生成AIは単体ツールではなく、システムとして設計する対象であると理解できた。

今後の展望

  • 動画から音楽生成への拡張
  • 監視カメラと連携した自動BGM生成システムへの応用
  • リアルタイム生成の速度向上の検証
ソースコード

画像生成

import os
from diffusers import StableDiffusionPipeline
import torch

os.makedirs("../outputs/images", exist_ok=True)

base = "c:\Image-to-Sound\outputs\images\lofi"

i = 1
while os.path.exists(f"{base}_{i}.png"):
    i += 1

pipe = StableDiffusionPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    torch_dtype=torch.float16
).to("cuda")

prompt = " " //enter the prompt

image = pipe(prompt).images[0]
image.save(f"{base}_{i}.png")

print(f"--- Complete! {base}_{i}.png ---")

音楽生成

import os
from transformers import BlipProcessor, BlipForConditionalGeneration
from PIL import Image
from audiocraft.models import MusicGen
from audiocraft.data.audio import audio_write

image_num = input("Number of Image: ")
image_path = f"c:/Image-to-Sound/outputs/images/lofi_{image_num}.png"

if not os.path.exists(image_path):
    print(f"Error: Not found: {image_path}")
    exit()

print(f"--- {image_path} ---")

processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
model_caption = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")

img = Image.open(image_path).convert("RGB")
inputs = processor(img, return_tensors="pt")
out = model_caption.generate(**inputs, max_new_tokens=50)
caption = processor.decode(out[0], skip_special_tokens=True)

print("caption:", caption)

music_model = MusicGen.get_pretrained("facebook/musicgen-large")
music_model.set_generation_params(duration=15)

wav = music_model.generate([caption])

output_filename = f"outputs/music/result_{image_num}"
audio_write(
    output_filename,
    wav[0].cpu(),
    music_model.sample_rate,
)

print(f"--- Complete! {output_filename}.wav ---")