wine-pairing-embed-130m

料理とワインを同じベクトル空間に置く、日本語の埋め込みモデル (Bi-Encoder)。料理とワインの相性の組で学習しており、合う料理とワインほどベクトルが近くなる。

主な使い道は次の 3 つ。

  • 料理から、合うワインを探す
  • ワインから、同じような料理に合うワインを探す (品切れのワインの代わりを探す、など)
  • 料理から、同じようなワインが合う料理を探す

1. モデルの概要

項目 内容
初期値 cl-nagoya/ruri-v3-130m
アーキテクチャ ModernBERT → 平均プーリング
パラメータ数 約 132M
ベクトルの次元 512
最大入力長 学習時は料理 128 トークン、ワイン 512 トークン
スコア関数 コサイン類似度
主要フレームワーク sentence-transformers

2. 使い方

料理もワインも、そのまま埋め込む。接頭辞は不要。

from sentence_transformers import SentenceTransformer

model = SentenceTransformer("mahiyama/wine-pairing-embed-130m")

dishes = [
    "牛肉のステーキ。厚切りの牛肉を焼いた料理。食材: 牛肉。調理法: 焼く。味付け: 塩、こしょう。味: うま味 高い、脂 中程度、重さ 高い。",
    "刺身。新鮮な魚介を生のまま切った料理。食材: 魚介類。調理法: 切る。味付け: 醤油、わさび。味: うま味 高い、脂 低い、重さ 低い。",
]
wines = [
    "種類: 赤ワイン。品種: カベルネ・ソーヴィニヨン。産地: アメリカ、カリフォルニア、ナパ・ヴァレー。味わい: 果実味 強め、ボディ しっかり。名前: ナパ・カベルネ・リザーヴ。",
    "種類: 白ワイン。品種: シャルドネ。産地: フランス、ブルゴーニュ、シャブリ。味わい: 酸味 強め、ボディ 軽め。名前: シャブリ。",
]

# 料理からワインを探す
dish_embeddings = model.encode(dishes)
wine_embeddings = model.encode(wines)
print(model.similarity(dish_embeddings, wine_embeddings))
# tensor([[ 0.1903, -0.1968],
#         [-0.1032,  0.3020]])

# ワインからワインを探す
print(model.similarity(wine_embeddings, wine_embeddings))
# tensor([[ 1.0000, -0.1175],
#         [-0.1175,  1.0000]])

# 料理から料理を探す
print(model.similarity(dish_embeddings, dish_embeddings))
# tensor([[ 1.0000, -0.0428],
#         [-0.0428,  1.0000]])

入力の書き方

学習と同じ形の文を入れると、精度がもっとも高くなる。

対象 形 例
料理 料理名。説明。食材: 〜。調理法: 〜。味付け: 〜。味: 〜。 牛肉のステーキ。厚切りの牛肉を焼いた料理。食材: 牛肉。調理法: 焼く。味付け: 塩、こしょう。味: うま味 高い、脂 中程度、重さ 高い。
ワイン 種類: 〜。品種: 〜。産地: 〜。年: 〜。味わい: 〜。名前: 〜。説明: 〜 種類: 赤ワイン。品種: カベルネ・ソーヴィニヨン。産地: アメリカ、カリフォルニア、ナパ・ヴァレー。味わい: 果実味 強め、ボディ しっかり。名前: ナパ・カベルネ・リザーヴ。
  • 料理は料理名だけでも使える。説明や食材を足すと、少し精度が上がる
  • ワインは、種類・品種・産地・名前を入れる。名前には産地や品種の手がかりが含まれることが多いため、削らない方が精度が上がる。説明の文 (香りや味わいの記述) があれば、さらに精度が上がる
  • 種類・品種・産地の無い、名前だけの入力は想定していない
  • 類似度の値は 0 付近を中心に分布する。値そのものではなく、同じ料理に対するワインの順位として使う

相性の例

料理 12 品とワイン 10 本を埋め込み、コサイン類似度を計算した結果を次に示す。料理は「入力の書き方」の形の文、ワインは「種類: 赤ワイン。品種: カベルネ・ソーヴィニヨン。」のような、種類と品種 (または産地) だけの短い文で入れた。値が大きいほど、そのワインが合うとモデルが見ている。

カベルネ・ソーヴィニヨン ピノ・ノワール シラー シャルドネ ソーヴィニヨン・ブラン リースリング シャンパーニュ ロゼワイン ソーテルヌ ポートワイン
牛肉のステーキ 0.31 0.22 0.19 -0.07 0.00 -0.06 -0.03 0.02 -0.12 -0.08
すき焼き 0.23 0.18 0.09 -0.01 0.08 0.00 0.03 0.13 -0.06 -0.18
鶏の唐揚げ 0.12 0.11 0.09 0.14 0.20 0.11 0.12 0.19 -0.11 -0.12
刺身 -0.04 0.01 -0.04 0.24 0.19 0.24 0.13 0.19 -0.10 -0.07
生牡蠣 0.07 0.02 0.00 0.18 0.11 0.25 0.24 0.13 0.00 -0.03
ブリ大根 0.06 0.08 0.02 0.07 0.13 0.07 0.12 0.13 -0.11 -0.15
カルボナーラ 0.08 0.06 0.09 0.15 0.08 0.07 0.16 0.13 -0.01 -0.06
マルゲリータ -0.03 0.12 0.11 0.04 0.02 0.16 0.16 0.16 -0.08 -0.16
麻婆豆腐 0.12 0.12 0.05 0.07 0.19 0.11 0.12 0.20 -0.04 -0.01
ブルーチーズ 0.06 0.11 0.09 0.06 0.04 -0.04 0.03 0.07 0.30 0.16
生ハム 0.04 0.13 0.06 0.05 0.00 0.04 0.11 0.28 -0.07 -0.08
チーズケーキ 0.04 -0.09 0.05 0.18 0.06 -0.02 0.09 0.02 0.22 0.23
  • 牛肉のステーキやすき焼きには赤、刺身や生牡蠣には白やスパークリング、ブルーチーズやチーズケーキには甘口のワインが上位に来る
  • 値は、同じ料理の中でワインを並べるための順位付けのスコアとして見る

3. トレーニング方法

初期値

cl-nagoya/ruri-v3-130m を初期値として、料理とワインの相性の組で追加学習した。

学習データ

相性の点数 (0〜3 点) を付けた料理とワインの組 99,691 件のうち、2 点以上の 53,220 件を anchor (料理) と positive (ワイン) の組とした。0.5 点以下の組は、難しい負例の候補に使った。形の例を次に示す。

{"anchor": "牛肉のステーキ。厚切りの牛肉を焼いた料理。食材: 牛肉。調理法: 焼く。味付け: 塩、こしょう。味: うま味 高い、脂 中程度、重さ 高い。", "positive": "種類: 赤ワイン。品種: カベルネ・ソーヴィニヨン。産地: アメリカ、カリフォルニア、ナパ・ヴァレー。味わい: 果実味 強め、ボディ しっかり。名前: ナパ・カベルネ・リザーヴ。"}
{"anchor": "刺身。新鮮な魚介を生のまま切った料理。食材: 魚介類。調理法: 切る。味付け: 醤油、わさび。味: うま味 高い、脂 低い、重さ 低い。", "positive": "種類: 白ワイン。品種: シャルドネ。産地: フランス、ブルゴーニュ、シャブリ。味わい: 酸味 強め、ボディ 軽め。名前: シャブリ。"}
  • 料理は 2,876 種類、ワインは 19,248 本
  • 言語モデルの採点は、同じ組を 2 回採点し、点数の差が 1 以内の組だけを使った (平均を点数とし、差が 1 の組は重みを半分にした)
  • ワインの文は、日本語のワインの商品説明から作った。相性を直接書いた文は、ワインの文から除いた
  • 開発と評価に使う料理とワインは、学習から外した

訓練方法

正例が複数ある組に対応した、対称の InfoNCE (対照損失) を使った。

  • 料理から見て、正例のワインを、同じバッチの他の組のワインと、難しい負例 1 本 (その料理で点数の低かったワイン。無ければ無作為のワイン) より上にする
  • ワインから見て、正例の料理を、同じバッチの他の料理より上にする
  • 同じ料理の別の正例は、負例として扱わないようにマスクする
項目 値
learning_rate 2e-5
num_train_epochs 2
per_device_train_batch_size 128
難しい負例 正例 1 件につき 1 本
温度 0.05 (コサイン類似度を 20 倍)
warmup 全体の 5%
weight_decay 0.01
学習時の最大入力長 料理 128 トークン、ワイン 512 トークン
混合精度 bf16
入力の接頭辞 なし
乱数シード 42

訓練時間は NVIDIA RTX PRO 6000 Blackwell Server Edition (96 GB) 1 枚で約 8 分 (832 ステップ)、GPU メモリの最大使用量は 45.9 GB。

4. ライセンス

本モデルの重みは CC BY-NC 4.0 で提供する。非商用の利用に限る。初期値の cl-nagoya/ruri-v3-130m は Apache License 2.0。

Downloads last month
38
Safetensors
Model size
0.1B params
Tensor type
F32
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for mahiyama/wine-pairing-embed-130m

Finetuned
(5)
this model