DAIaryX

Phi-3.5-visionで朝昼晩の食事画像から栄養バランスを聞いてみる

しん

Phi-3.5-visionで朝昼晩の食事画像から栄養バランスを聞いてみる

はじめに

マルチモーダルモデルのPhi-3.5-visionを試していましたが、複数画像を扱うサンプルがあったので、普段の食事から栄養バランスを聞いてみたいと思います。栄養バランスを回答するには、食事に何が入っているか認識する必要がありますが、判断できるでしょうか?

Phi-3.5-visionとは?

マイクロソフトが開発した最先端のマルチモーダルAIモデルです。
単一画像の理解や文字認識だけでなく、チャートの解釈や動画の要約など、複雑なタスクまでこなせるそうです。

機能

パラメータは4.15Bなので8G以上のVRAMが必要で、処理する画像が多いほどさらにVRAMを使うようです。
今回試したのは3枚の画像でしたが、15G使っていました。

動作環境

OS

Ubuntu 24.04

GPU

Nvidia RTX3090

Nvidia RTX3060

メモリ

24G

LLM

https://huggingface.co/microsoft/Phi-3.5-vision-instruct

git clone

フォルダを作成し、huggingfaceからcloneします。
大きなファイルがあるため、git lfsが必要です。

mkdir llm
cd llm
git lfs install
git clone https://huggingface.co/microsoft/Phi-3.5-vision-instruct

パッケージインストール

venvでPython環境を分けてインストールします。

python -m venv venv
source venv/bin/activate
pip install torch torchvision torchaudio accelerate transformers flash_attn

サンプルコード実行

サンプルコードを実行します。
vi vision.pyとして以下を保存します。
サンプルコードはマイクロソフトのプレゼンを20枚読み込んでいましたが、朝昼晩の食事画像に変更し、プロンプトを変更します。

from PIL import Image 
import requests
from transformers import AutoModelForCausalLM
from transformers import AutoProcessor

model_id = "microsoft/Phi-3.5-vision-instruct"

# Note: set _attn_implementation='eager' if you don't have flash_attn installed
model = AutoModelForCausalLM.from_pretrained(
model_id,
device_map="auto",
trust_remote_code=True,
torch_dtype="auto",
_attn_implementation='eager'
)

# for best performance, use num_crops=4 for multi-frame, num_crops=16 for single-frame.
processor = AutoProcessor.from_pretrained(model_id,
trust_remote_code=True,
num_crops=4
)

images = []
placeholder = ""

# Note: if OOM, you might consider reduce number of frames in this example.
urls = ["https://daiaryx.com/test1.webp","https://daiaryx.com/test2.webp","https://daiaryx.com/test3.webp"]

for i, url in enumerate(urls):
    images.append(Image.open(requests.get(url, stream=True).raw))
    placeholder += f"<|image_{i+1}|>\n"

messages = [
{"role": "user", "content": placeholder+"Please tell us about the nutritional balance and impressions of the images of eating out for breakfast, lunch, and dinner."},
]

prompt = processor.tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)

inputs = processor(prompt, images, return_tensors="pt").to("cuda:0")

generation_args = {
"max_new_tokens": 1000,
"temperature": 0.0,
"do_sample": False,
}

generate_ids = model.generate(**inputs,
eos_token_id=processor.tokenizer.eos_token_id,
**generation_args
)

# remove input tokens
generate_ids = generate_ids[:, inputs['input_ids'].shape[1]:]
response = processor.batch_decode(generate_ids,
skip_special_tokens=True,
clean_up_tokenization_spaces=False)[0]

print(response)

読み込む画像

実行

python vision.py

出力

画像には、タンパク質、野菜、炭水化物を組み合わせた栄養バランスの取れたアプローチを示唆するさまざまな料理が描かれています。最初の画像は、卵、トースト、サラダが添えられた朝食プレートで、タンパク質、繊維質、ビタミンがバランスよく含まれています。
2 番目の画像には、野菜が入った丼とスープが描かれており、炭水化物、タンパク質、野菜の組み合わせが提供されます。
3 番目の画像は、野菜を添えたスクランブルエッグとスープのプレートを示しています。これは、タンパク質、繊維、ビタミンを含むバランスの取れた食事を提供します。
全体として、これらの食事はバランスが取れており、栄養価が高く、健康的な食事に適しているようです。

結果

最初の画像は上島珈琲ホテルの朝食でほぼあってますが、デザートとコーヒーが抜けてます。
2番目の画像は土鍋鯛茶漬けですが、これはちょっと判断に必要な情報がないですね。野菜が入った丼も間違ってはいないです。
最後は海老チャーハンとトムヤムヌードルです。スープに見えてもおかしくないですが、スクランブルエッグは違いますね。

まとめ

画像から食事の内容を判断し、それぞれの画像で栄養バランスについて回答してくれました。
精度はまだまだですが、聞かれた質問に対して回答はできてそうです。
複数の画像から一貫した回答を生成してくれるので、工夫してサービスに応用していきたいです。

15

記事数

しん