はじめに
はじめまして。
国内のSIer企業でエンジニアをしている Taiki です。
今回、Qiita のキャンペーン「OpenAI・Claude API と互換性あり! 国内AIモデル推論プラットフォーム『ai& Inference』を使ってみよう」に参加してみます。
せっかくの機会なので、一時期はやった「写真からのカロリー計算」を題材に、牛丼とコンビニのそぼろ弁当を対象に、OpenAI の GPT(gpt-5.4系) と ai& Inference の激安オープンモデルを、費用と精度の両面でガチ比較してみました。
結論を先に言うと、意外な絵が出てきました。
- 牛丼は全モデルがほぼ的中 (誤差1~8%) 。ところが、そぼろ弁当は全モデルが大きく外す (誤差62~91%) 。
→つまり、「AIはカロリーを当てられるか?」の答えは料理による。しかも、モデルの優劣まで料理でひっくり返る。 - 1コールの実コストが本家GPTの約1/30(入力トークン単価では十数分の一)の激安オープンモデルが、弁当では最も正確でした。
⚠️ 注意:
本結果はモデルの精度比較が目的で、実際の栄養・健康管理に用いるものではありません。カロリーは推定値です。サンプルは今回の2品のみで、一般化はできません。
環境構築
「ai& Inference」は OpenAI / Claude API 互換の、国内データセンターで動くAI推論プラットフォームです。
まずは API キーを発行します。環境構築は本題ではないのでかいつまんで書きます。詳しい手順は下記が参考になります。
①ユーザー登録
https://console.aiand.com にアクセスして、ユーザー登録を完了させます。
② クレジットを追加(プロモコードで$50無料)
ホーム画面右上の「Credits: $0.00」をクリックしてクレジットを追加します。キャンペーンのプロモコードで $50分(約8,000円) を無料で使えます(コンソールの Credits に $50 反映を確認)。プロモコードは公式イベントページで確認できます。
サインアップ時にクレジットカード情報の入力は求められず、約8,000円分($50)を試せました。ありがたいですね。
③ API Key を発行
ホームの「API Keys」から KeyName を決めて発行するだけ。数クリックで取得できました。
🔑 発行した API キーは
.envなどに保管し、コードやスクリーンショットに残さないよう注意しましょう
カロリー算出実験
実験内容
すき家の牛丼とコンビニのそぼろ弁当の2品を題材に、料理写真からカロリー(と料理名・PFC)を推定させます。
出力は毎回同じ固定JSONスキーマ(dish_name, total_kcal, protein_g, fat_g, carb_g, confidence)で受け取り、パースして集計します。全リクエストの usage・レイテンシ・生応答は JSONL に1行ずつ記録し、
記事の数値・グラフはすべてこのログから機械生成しています(手打ちゼロ)。
実験設定
| 項目 | 内容 |
|---|---|
| 料理 | ①コンビニ そぼろ弁当(正解 579 kcal・パッケージ栄養成分表示より・単一商品の参考値・確認日2026-07-08)②すき家 牛丼並盛(正解 695 kcal・すき家公式 栄養成分一覧・更新日2026-07-03) |
| モデル | OpenAI: gpt-5.4 / gpt-5.4-mini、ai&: gemma-4-31b-it / kimi-k2.6(いずれもvision対応・料金は実APIと公式で確認、2026-07-08) |
| 条件 | 写真のみ・temperature=0・各写真につき3試行(ブレも記録) |
| 指標 | APE(絶対%誤差 ` |
料金の出典と確認日、モデルIDはすべて実API(/models)と公式ページで確定しています(推測は排除)。
なお OpenAI のフラッグシップ GPT-5.5($5/$30・1Mトークンあたり)は高価なため今回は対象外とし、実務的な価格帯の gpt-5.4 / gpt-5.4-mini を採用しました(タイトルを「最新級」としているのはこのためです)。
使用コード(要点)
やっていることは「画像+プロンプトを投げて、固定JSONで受け取り、集計する」だけです。核心は次の4ステップ。
from openai import OpenAI
# ① クライアント: base_url を差し替えるだけで本家↔ai&を切替(キー以外は同じコード)
def make_client(api_key, base_url=None):
return OpenAI(api_key=api_key, base_url=base_url) if base_url else OpenAI(api_key=api_key)
# ② プロンプト: 料理名・kcal・PFC を「JSONオブジェクトのみ」で返させる
PROMPT = (
"料理写真から、料理名・推定総カロリー(kcal)・タンパク質/脂質/炭水化物(g)・確信度(0〜1)を"
"推定してください。出力は次のJSONのみ(前後に説明文を付けない):\n"
'{"dish_name": string, "total_kcal": number, "protein_g": number, '
'"fat_g": number, "carb_g": number, "confidence": number}'
)
# ③ 画像を data URI(base64)にして 1 メッセージに積む
def build_messages(prompt, image_paths):
content = [{"type": "text", "text": prompt}]
for p in image_paths:
content.append({"type": "image_url", "image_url": {"url": to_data_url(p)}})
return [{"role": "user", "content": content}]
# ④ 呼び出し(temperature=0)→ 生JSONと usage を取得
resp = client.chat.completions.create(model=model_id, messages=messages, temperature=0)
raw = resp.choices[0].message.content
usage = resp.usage # prompt_tokens / completion_tokens → コスト計算に使う
あとは JSON をパースして、正解値との誤差(APE)と実コストを出すだけです。
import json
est = json.loads(raw) # JSON が崩れたら 1〜2 回だけ「JSONで出し直して」と再要求
ape = abs(est["total_kcal"] - truth_kcal) / truth_kcal * 100 # 絶対%誤差
cost_jpy = (usage.prompt_tokens * in_price_usd_per_1m
+ usage.completion_tokens * out_price_usd_per_1m) / 1e6 * usd_jpy
全リクエストを JSONL に1行ずつ記録し、表・グラフはこのログから機械生成しています(数値の手打ちゼロ)。
モデルID・単価・正解kcal は設定ファイル(config.yaml)に集約し、/models と公式で確認した値だけを入れています。
プロンプトの版管理・JSON崩れ時のリトライ・vision非対応やAPIエラーの分類など、全コードは GitHub で公開しています。
👉 リポジトリ: https://github.com/Taiki0629/CalorieLensPoC (実装は 30_development/)
結果 ― モデル別ランキングは「料理で逆転」する
4モデルで、2品それぞれの平均APEと料理名正解率を並べます。
そぼろ弁当(正解 579 kcal)
| 順位 | モデル | 平均APE | 料理名正解率 |
|---|---|---|---|
| 1 | gemma-4-31b-it | 61.5% | 100% |
| 2 | gpt-5.4-mini | 69.3% | 100% |
| 3 | gpt-5.4 | 75.6% | 100% |
| 4 | kimi-k2.6 | 90.7% | 83% |
すき家 牛丼(正解 695 kcal)
| 順位 | モデル | 平均APE | 料理名正解率 |
|---|---|---|---|
| 1 | kimi-k2.6 | 1.2% | 100% |
| 2 | gpt-5.4 | 3.6% | 100% |
| 2 | gpt-5.4-mini | 3.6% | 100% |
| 4 | gemma-4-31b-it | 7.9% | 100% |
2つの表を見比べると、弁当で最下位だった kimi が牛丼では最良、弁当で最良だった gemma が牛丼では最下位。
順位が丸ごとひっくり返っています。「どのモデルが一番か」は料理によって変わり、万能に最良のモデルは
今回の2品では見当たりませんでした。
弁当のAPE(青)が左→右で上がるのに対し、牛丼(黄)は逆に下がっていく——同じ4モデルでも、
得意な料理が正反対になっているのが一目で分かります。
もう一点。料理名はほぼ全モデルが正解(弁当を「弁当/そぼろ弁当」、牛丼を「牛丼」と認識)。
つまりモデルは何の料理かは分かっているのに、弁当のカロリーだけ大きく外す。
「料理を認識できること」と「カロリーを当てられること」は別物でした。
コスト ― 「1日1万リクエスト」で費用を逆算
1リクエスト(写真1枚)の実コスト(usage × 各モデル単価、USD建てを為替でJPY換算)を、「毎日1万人が1回ずつ撮影するアプリ」に逆算します(弁当の写真1枚あたり)。
| モデル | 1コール | 1日1万リクエスト |
|---|---|---|
| gemma-4-31b-it | ¥0.021 | 約¥207 |
| gpt-5.4-mini | ¥0.179 | 約¥1,786 |
| gpt-5.4 | ¥0.629 | 約¥6,293 |
| kimi-k2.6 | ¥1.545 | 約¥15,450 |
円換算は USD/JPY = 161.87(tradingeconomics・2026-07-07 時点のスナップショット)で算出しています。
gemma は gpt-5.4 の約1/30、kimi の約1/75のコスト。しかも弁当では gemma が精度も最良でした。
一方 kimi は「入力単価は安い」にもかかわらず、回答前に大量の推論トークンを消費するため、**1コールが最も高く(¥1.5前後)・最も遅い(約10〜17秒)**という結果に。
per-token 単価の安さと、実際の1コールあたりコストは一致しないという良い教訓です。
コスト×精度の散布図では、下の集団(すき家・低APE)と上の集団(弁当・高APE)にくっきり分離します。
同じモデルでも料理でAPEが激変することが一目で分かります。
メリット
手軽さ ― base_url を1行差し替えるだけ
ai& Inference は OpenAI 互換APIです。先ほどの make_client のとおり、
OpenAI(..., base_url="https://api.aiand.com/v1") と1行差し替えるだけで、本家GPT向けに書いたコードをそのまま国内DCのオープンモデルに投げられます。本家とオープンモデルの比較コードが1本化できるのが、今回いちばん助かった点でした。
モデルの多さ ― 1キーで複数のオープンモデル
ai& は1つのエンドポイントで複数のオープンモデルを切り替えられます。対応モデル・料金・画像入力(vision)対応は /models で確認できます。本記事では、この一覧から vision 対応を実APIで確認できたモデル(gemma と kimi)を採用しました(モデルID・料金・vision可否は推測せず、実APIと公式情報で確定しています)。
考察
-
最大の発見:過大評価は「モデルの癖」ではなく「料理固有」。定番でシンプルな牛丼は全モデルがほぼ的中。一方、そぼろ+コロッケ+フライ+ハンバーグと具材が多い弁当は全モデルが大幅に過大評価しました。
精度を決めるのは料理の複雑さ・定番度であって、モデルの高い/安いではなさそうです(今回の2品では)。 - 激安オープンモデルの健闘:gemma は弁当で最良精度+最安。「安い=劣る」は今回は成り立ちませんでした。
-
国内データセンター × オープンモデルという選択肢:食事写真は体型・健康と結びつく個人データです。
海外クラウドに送りたくないニーズに対し、国内DCで完結する激安オープンモデルが実用精度を出せるなら、クローズドな海外APIでは満たせない要件(データの国内完結)に応えられます。
締め
写真1枚でAIにカロリーを当てさせる試みは、「当たる料理と当たらない料理がはっきり分かれる」「モデルの優劣は料理で逆転する」「国内DCで動く激安オープンモデルが本家GPTに精度で勝つ場面がある」という、教科書的でない結果を見せてくれました。
健康データを扱うアプリを国内DCのオープンモデルで、しかも桁違いに安く組める——今回の2品は、その選択肢が現実的であることを示す小さな証拠になりました。
ai& Inference は base_url 差し替えだけで試せて、プロモコードで無料枠もあります。気になった方はぜひ手元の写真で試してみてください。
再現情報
-
GitHub リポジトリ: https://github.com/Taiki0629/CalorieLensPoC
— コード・プロンプト・条件・実験ログ(JSONL)・設定・図の生成スクリプト一式。 - 図表は
calorielens score/calorielens visualizeでログから再生成できます(実装は30_development/)。 - モデル料金・vision対応・seed対応は実API(
/models)と公式ページで確認(2026-07-08)。 - 正解kcal 出典: 弁当=パッケージ栄養成分表示、牛丼=すき家(ゼンショー)公式栄養成分一覧。
⚠️ 再掲: 本結果はモデル精度比較が目的で、実際の栄養・健康管理には用いません。カロリーは推定値、
サンプルは今回の2品のみです。弁当は同一商品を複数カット撮影した平均、牛丼は第三者提供の写真1枚での比較です。




