nikkie-ftnextの日記

イベントレポートや読書メモを発信

そうか、kfpでcompileしたYAMLファイルは、Vertex AI Pipelinesにもアップロードできるのか!

はじめに

バーン! nikkieです。

小さなネタではあるのですが、アハ体験があったので記します。

目次

「Kubeflow Pipelines v2 で変わる機械学習パイプライン開発」

2024/03/20 第39回 MLOps 勉強会の資料を後追いしていました。

杉山さんがKubeflow Pipelines v2の発表をされていて、その中で目を引いたのがこちら

至るまでの流れとしては

  • 用語解説(後述
  • DSLを書いてみよう(KFP SDK

の後にこちらのアップロードです。

過去にKubeflow Pipelinesを触っていて、kfpも知っていました。
私の中では、kfpを使ってPythonファイルにDSLを書き、そこからYAMLファイルに変換して、それをKubeflow Pipelinesにアップロードという理解でした。

ここにYAMLファイルをGoogle CloudのVertex AI Pipelinesにアップロードしてもよいという選択肢が示されたのです!
k8sクラスタ(Kubeflow)が要るものと思い込んでいたので、目からウロコでした。
マネージドサービスってすげ〜

Hello Worldを試す

  • Python 3.11.4
  • pip install kfp
    • 2系をインストール(2.7.0が入りました)

ライブラリバージョン

cachetools==5.3.3
certifi==2024.2.2
charset-normalizer==3.3.2
click==8.1.7
docstring_parser==0.16
google-api-core==2.18.0
google-auth==2.29.0
google-cloud-core==2.4.1
google-cloud-storage==2.16.0
google-crc32c==1.5.0
google-resumable-media==2.7.0
googleapis-common-protos==1.63.0
idna==3.6
kfp==2.7.0
kfp-pipeline-spec==0.3.0
kfp-server-api==2.0.5
kubernetes==26.1.0
oauthlib==3.2.2
proto-plus==1.23.0
protobuf==4.25.3
pyasn1==0.6.0
pyasn1_modules==0.4.0
python-dateutil==2.9.0.post0
PyYAML==6.0.1
requests==2.31.0
requests-oauthlib==2.0.0
requests-toolbelt==0.10.1
rsa==4.9
six==1.16.0
tabulate==0.9.0
urllib3==1.26.18
websocket-client==1.7.0

Google Cloudは、過去に以下の記事で素振りした跡地プロジェクトを再利用しました。

DSLを書いたスクリプト

スクリプトを実行して生成されたYAMLファイルを、アップロードします!

Runが作られ、実行されました🙌

見事な整理

杉山さんのスライド、用語の整理が見事でした👏

KubeflowとVertex AIが根っこは同じと理解しました

この整理があったので、kfpがcompileして出力するYAMLファイルが、Kubeflow Pipelinesにも、Vertex AI Pipelinesにも使えるという点をスルーせずに気づけました。

残された宿題

過去に触ったkfpは1.8系でした。

過去記事に沿ったYAMLファイルを当初Vertex AI Pipelinesにアップロードしたのですが、これは弾かれてしまいます。

ファイルの内容が無効です

kfp v2への移行が必要なのかなと考えていて、杉山さんの記事を元に手を動かしてみたいです。
(これができると手元の既存の資産をVertex AI Pipelinesでも動かせる世界が来るので!)

終わりに

KubeflowとVertex AIって理解がぐちゃぐちゃだったのですが、第39回 MLOps 勉強会の発表資料のおかげで、Kubeflow Pipelinesを少し触った地点からVertex AI Pipelinesに至る道が見えました!

  • kfpでcompileした結果のYAMLファイルは、Google CloudのVertex AI Pipelinesにアップロードできる!
  • kfpは1系から2系への変更があり、2系にキャッチアップしたい(宿題事項)

Pythonの仮想環境、最近は .venv という名前で作っています

はじめに

バーンブレイバーン、アイうたじゃなくてボーボボ!! nikkieです

Pythonの仮想環境、--upgrade-depsオプションを激推しするくらいヘビーユースしています。

私事で恐縮ですが、私nikkieは今般、仮想環境のお相手(=実体のディレクトリ)の名前を venv から .venv に変えたことを、読者の皆さまにご報告いたします。
※本記事は小ネタです

目次

わたしと仮想環境

ご報告のサマリ

  • これまで
    • python -m venv venv --upgrade-deps
  • これから
    • python -m venv .venv --upgrade-deps

これはvenvモジュールの__main__.pyを実行しに行きます1
https://github.com/python/cpython/blob/v3.12.2/Lib/venv/__main__.py
このスクリプトは引数を受け取ります(venv.venvの部分)。
引数には仮想環境とするディレクトリのパスを(複数)指定できます。

このたび、仮想環境のディレクトリ名を.venvに変えました。

理由:公式ドキュメントに準拠したくて

ふとPythonチュートリアルを見た時に、.venvという名前で作っていることに気づいたんですよ。

12.2. 仮想環境の作成より

仮想環境の一般的なディレクトリの場所は .venv です。

この名前は、通常はシェルで隠されているため、ディレクトリが存在する理由を説明する名前を付けても、邪魔にはなりません。
また、一部のツールでサポートされている .env 環境変数定義ファイルによるクラッシュも防止します。

標準ライブラリのvenvのドキュメントでも.venvという名前です。

よく使われるターゲットディレクトリの名前は .venv です(仮想環境の作成より)

私が見た範囲の公式ドキュメントでは、どうやら現在は.venvという名前みたいです。

.venvに変えて嬉しい小さな点(macOS

macOSで開発している中で、source veくらいでタブキーで補完しようとすると、2つ候補が出るようになりました。

  • venv
  • venc_data_dump

後者はffmpegをインストールしたからと思われます2

仮想環境のディレクトリの名前を.venvとすると、source .vでタブ補完ができてサクサクです

日本語のPython入門ドキュメントでは名はenv

「(ここに大きな主語を置いて)公式ドキュメントに合わせた名前の.venvにするべき」なんてことは一切考えていません。
取るに足らない好みの問題だと思います。

私がPythonに入門したタイミングでは、python -m venv venvを教わった気がします。
そのまま長らく使い続けてきました。
結構長いことpython -m venv venvで1つの呪文のように思っていて、2つ目のvenvが仮想環境のディレクトリ名だと気づくのに時間がかかりました。

日本語で読める入門ドキュメントでは、現在、仮想環境のディレクトリの名前は env としているようです。

python -m venv envならenvというディレクトリを作っているんだなとわかりやすいので、これはこれでよいと思います👍

終わりに

仮想環境のディレクトリの名前について、私の好みをお伝えします

  • .venvに行き着きました。公式ドキュメントとおそろです
  • venvでもできる仮想環境の動きに違いは全くありませんが、python -m venv venvが1つの変えてはいけない呪文のように思ってしまっていたので、私の中ではポイント低いです
  • 日本語のドキュメントでは、現在はenvのようです。これはこれでよいと思います

MLflow素振りの記:2.8からサポートされたLLM-as-a-Judgeを触る

はじめに

あらたなユーフォニアム...!! nikkieです。

MLflowを触ってみました。
なんでもLLM-as-a-Judgeができると聞きまして

目次

「静的データセットで評価する」のコードを動かしてみる

検索して見つけたドキュメントに沿って手を動かします。
https://docs.databricks.com/ja/mlflow/llm-evaluate.html#evaluate-with-a-static-dataset
ちなみに原文は「Evaluate with a static dataset

ここでは、質問応答の例が2つあります

  • 質問:What is MLflow?
  • 質問:What is Spark?

各質問には正解(ground truth)と予測(prediction)があります。

predictionとground truthの評価を行いたい状況という理解です。
mlflow.evaluate()を呼んで、LLM-as-a-Judge1する例です。

results = mlflow.evaluate(
    data=eval_data,
    targets="ground_truth",
    predictions="predictions",
    extra_metrics=[mlflow.metrics.genai.answer_similarity()],
    evaluators="default",
)

extra_metrics引数がLLM-as-a-Judge(の方法の1つ)を指定しています。

MLflow 2.8 リリースブログより

MLflow 2.8: Automated Evaluation参照2

We've extended the MLflow Evaluation API to support GenAI metrics and evaluation examples.

「MLflow Evaluation API」の部分はリンクになっていて、mlflow.evaluate()に関するドキュメントから「Evaluating with LLM」が案内されています。
https://mlflow.org/docs/latest/models.html#evaluating-with-llms

You get out-of-the-box metrics like toxicity, latency, tokens and more, alongside some GenAI metrics that use GPT-4 as the default judge, like faithfulness, answer_correctness, and answer_similarity.

動作環境 & スクリプト

  • Python 3.11.8
  • pip install mlflow tiktoken openai
    • mlflow==2.11.3
    • tiktoken==0.6.0
    • openai==1.16.2
  • 環境変数OPENAI_API_KEYを設定しておく

評価結果を確認

スクリプトを実行

See aggregated evaluation results below:
{'answer_similarity/v1/mean': 3.5, 'answer_similarity/v1/variance': 0.25, 'answer_similarity/v1/p90': 3.9}
See evaluation table below:
            inputs  ...                 answer_similarity/v1/justification
0  What is MLflow?  ...  The provided output has moderate semantic simi...
1   What is Spark?  ...  The provided output aligns closely with the ta...

[2 rows x 5 columns]

「MLflowってmlflow uiでブラウザで見られたよな」と思い出し3、眺めてみました

MLflowは裏で一体何をしたのか

mlflow.metrics.genai.answer_similarityは今回の設定だとGPT-4で評価しています!4

https://mlflow.org/docs/latest/python_api/mlflow.metrics.html#mlflow.metrics.genai.answer_similarity

Defaults to “openai:/gpt-4”.

評価のプロンプトはここにあるようです。
https://github.com/mlflow/mlflow/blob/v2.11.3/mlflow/metrics/genai/prompts/v1.py#L99

  • 正解に対する予測の意味の類似具合を評価する(definition参照)
  • 1-5の5段階で評価する(抽象的な定義を与える。grading_prompt
  • 2と4の例を与える(default_examples
    • 「What is MLflow?」が例ですが、手元のpredictionはこのプロンプトと同じテキストではありませんでした
  • justificationにGPT-4の評価の理由がありそうでした
    • MLFlowの質問の方(3と評価):Therefore, it demonstrates moderate, but not substantial, semantic similarity.
    • PySparkの質問の方(4と評価):it demonstrates substantial semantic similarity.

終わりに

2件のデータでMLflowのLLM-as-a-Judgeを体験してみました。
mlflow.evaluate()正解と予測を渡して、LLM-as-a-Judgeの設定(=extra_metrics引数の指定)をすればできるのですね。
全然経験ないので間違っている理解の可能性高そうですが、mlflow.evaluate()ってモデルをなにか1つ指定してその予測を評価するものだと思うので、モデルを指定せずに正解と予測の2種のデータを指定するだけでよいというのが機能拡張なのかなととらえています。

MLflowの概念はとても目新しいので、引き続き触っていこうと思います。

P.S. MLflowに興味を持ったきっかけは

2月のMLOps勉強会なのです。


  1. こちらの論文で出された概念と理解しています。 この記事で知りました。
  2. このブログのタイトルにPart 2とあるのは、こちらの第2弾の内容も含むからではないかと考えています。
  3. 参考記事
  4. 切り替えたプルリクエストも見つかりました(経緯はまだ不明)

読書&写経ログ | #ちょうぜつ本 第8章 Visitorパターン 〜Sphinx拡張開発の経験、そういうことだったのか!〜

はじめに

変更しやすいコードが書けないのにソフトウェア開発とか舐めているのですか

天使様、ごめんなさい〜、nikkieです1

「かわいい」と技術書が夢の合体を果たした、ちょうぜつ本(『ちょうぜつソフトウェア設計入門』2)!🤗
昨年から読書会を共同主催しており、現在は第8章「デザインパターン」を読み進めています。
直近読んだ範囲から、Visitorを取り上げます。来訪者編です!

目次

前回のちょうぜつ本!

前から順に読み進めて第8章に突入し、読書会では範囲を細かくしてじっくりと読み進めています。

Compositeパターンは、自己再帰的なデータ構造。
複数と単数の同一視は、頭いいですね。

Visitorパターン

Compositeパターンのデータの各要素を操作する場合に、visitor(訪問者)を渡して訪問者に要素の操作をしてもらいます

  • データ構造の各要素は、訪問者を受け入れるようにしておくだけ
    • 自身を訪問者に渡して、訪問者が要素を操作する
  • 操作を拡張可能にできる(要素を操作する訪問者を拡張して渡せばよい)

操作対象が操作の詳細を決められないとき、Visitor を受け入れられるようにだけしておけば、操作の詳細を除いて先に安定させてしまえる、というのがこのパターンです。

公開時期的にもマッチしたサンタクロースのたとえです(煙突はvisitor(サンタクロース)をaccept)。

今回はピンときたVisitorパターン

私は木構造のデータに関心があり(Sphinx拡張3や抽象構文4)、Visitorパターン自体は名前を知っていました。
Visitorという概念をつかもうと、手を動かすのと並行して結城先生本を紐解きもしましたが、いまいちピンときていませんでした。
ちょうぜつ本のコードは具体のVisitorには全く言及していないがゆえに、私には分かりやすかったです(登場人物が多くて私が混乱していたふしがあります)

データ構造

  • Node
    • accept()メソッドでvisitorを受け入れる
      • 自身をvisitorにどう渡すかだけ実装
  • Branch
    • Nodeを継承=BranchNodeである
    • accept()メソッドでvisitorを受け入れる
      • 自身と子要素をvisitorにどう渡すかだけ実装
class Node:
    def accept(self, visitor) -> None:
        visitor(self)


class Branch(Node):
    def __init__(self, *args: Node) -> None:
        self.children = list(args)

    def accept(self, visitor) -> None:
        super().accept(visitor)

        for child in self.children:
            child.accept(visitor)

visitorの実装は読者に委ねられていたので、要素をprint()するだけとしました。

class ExampleVisitor:
    def __call__(self, acceptable: VisitorAcceptable) -> None:
        print(acceptable)

データ構造を用意します。

classDiagram
    root *-- node
    root *-- branch
    branch *-- left
    branch *-- right

root.accept(ExampleVisitor())rootにvisitorを渡して呼び出すだけで、visitorが各要素を処理します!

<__main__.Branch object at 0x103143210>
<__main__.Node object at 0x1031431d0>
<__main__.Branch object at 0x103143150>
<__main__.Node object at 0x1031430d0>
<__main__.Node object at 0x103143110>

結城先生本では、要素がvisitorを受け入れて自身をvisitorに渡し、visitorが各要素を処理するという部分が当時の私には理解しきれませんでした(まだるっこしいという誤解をしました)。
ちょうぜつ本の例はvisitorの実装に言及していないので、「こういうデータ構造にvisitorを渡すのか」と気づけて、私にはブレイクスルーとなりました。

Sphinx(やdocutils)とつながりました!

(ここのトピック、詳しくは別記事としたいと思います)

docutils(バージョン 0.20.1)のソースコード(docutils/nodes.py)を覗くと、Visitorパターンがありました。

class Node:
    def walk(self, visitor):
        # 省略  # 自身をvisitorにどう渡すかを実装している

    def walkabout(self, visitor):
        # 省略


class NodeVisitor:

    """
    "Visitor" pattern [GoF95]_ abstract superclass implementation for
    document tree traversals.

    省略
    """

    def dispatch_visit(self, node):
        # 省略  # Nodeの操作を実装している

    def dispatch_departure(self, node):
        # 省略

また、SphinxではdocutilsのNodeVisitorを継承したクラスがトランスレイター5です!
https://github.com/sphinx-doc/sphinx/blob/v7.2.6/sphinx/builders/__init__.py#L62

from docutils import nodes

class Builder:
    default_translator_class: type[nodes.NodeVisitor]

つまり、Sphinx拡張を書くとき、私は知らず知らず(さらに理解至らず至らず)のうちにVisitorパターンを使っていたのです!

Sphinxはユーザが要素を追加できるんですよね。
ユーザが追加する要素への操作は、docutilsやSphinx側のソースコードにあらかじめ定義しておけません。
要素を追加したユーザがvisitor(トランスレイター)も合わせて追加することで成り立っているという理解です。
つまり、要素を追加できるというSphinxの拡張性は、Visitorパターンに支えられていると思われます。

また、ユーザが要素を拡張して作ったデータ構造について、要素の取り出し方(イテレータ)を事前に定義するのも難しそうです。
どの要素にもvisitorを渡すことで操作するというのは、とてもかしこいですね!

終わりに

ちょうぜつ本 8章よりVisitorパターンでした。
データ構造の各要素は訪問者を受け入れるようにしておき、訪問者が要素を操作します。
これにより、操作の詳細は訪問者で定義すればよく、拡張も可能になります(Sphinxの例)

来訪者編は、いいぞ!


  1. ちょうぜつ本読書ログシリーズではおなじみのこちらの書き出し。元は『お隣の天使様にいつの間にか駄目人間にされていた件』の「家事ができないのに一人暮らしとか舐めているのですか」です。配信では1話の17:40くらいです! 天使様は2024年の干支だと思っています(過激派)
  2. 技術書界のきららとして知られます。アニメ化してほしいな〜
  3. 応援ください!
  4. 一例です
  5. ビルダーとトランスレイター

5/7(火) pixivさんオフィスでの #エンジニアニメ でアニメから得た学びを話します。にしこりさんのお話も聞けるぞ!

はじめに

俺が要石なんだ、nikkieです。

タイトルがすべての登壇お知らせ記事です。
5/7はpixivさんのオフィスで僕と握手!

目次

エンジニアがアニメから得た学び

この会では、ゆるくエンジニアの皆さんが「アニメに影響を受けて考えが変わった話」や「アニメから学ぶモチベーションの維持」などトークも聴きつつ、参加者の皆さんが交流できる場にしたいと思っています。

発起人はうーたんさん!

お心遣いが行き届いている...👏

わーい!にしこりさんのお話が聞けるぞ〜

めちゃ楽しみなんです!!

Pとしてもエンジニアとしてもめちゃめちゃ尊敬しております。
お会いするのが、楽しみだ...(緊張してきた)

野良LTもできるよ!

タイムテーブルには現在、ブルーロック! SHIROBAKO

さらに

アニメから得た学びトーク、全部で何本聞けるのでしょう(わくわく)

アニメトークするのは、あにべん以来では

あなた、発表資料にアニメネタを入れるのは大得意でしょ1

2018年にあにべんという勉強会がありました。

そこで、「何かを決めるということ」というLTをしています。

LTスライドはこちら
https://github.com/ftnext/2018_LTslides/blob/2c5f0ea250f816537129cfc2e8c7585d5689a572/aniben_August_imas/PITCHME.md

もしかしたら、もっといい方法があるのかもだけど でも、私は天海春香だから。

「私は天海春香だから」で決めることへの不安が解消された

ここから時は流れて6年近く。
いろいろな作品との出会いもありました。
今回は何をお話ししようかな〜

ポチッとしました

いまなら割引 & 送料無料でお得になってるポチットップスもよろしくお願いします!

味ついてて、おいしいです!

終わりに

5/7(火)に エンジニアがアニメから得た学び(オフライン限定イベント)で5〜10分お話しします。

  • アニメから得た学びについてのトークを聞きたい方
  • にしこりさんのお話を聞きたい方(「自己効力感を二次元アイドル作品から得ながら社会人としての成長を超加速させる」)
  • ポチットップスを賞味してみたい方

ぜひぜひ当日pixivさんオフィスで握手しましょう〜

P.S. 裏話、企画発祥

うーたんさんのLTスライドより

左の写真は、喫茶ドリーム。そこで今回の話が立ち上がっています。くふふ♪


  1. 初手奇声のこちら

ことみんさんによる「エンジニア基礎 ウィルゲート2024年度エンジニア新卒研修」。読んでいて「それな!」祭り👏 これはマジで受けたい!

はじめに

トワラー、めっちゃいい😭 nikkieです。

研修「エンジニア基礎」資料が話題です。
200ページを超えるスライドを読んでのメモ、「それな!」祭りです。

目次

エンジニア基礎 ウィルゲート2024年度エンジニア新卒研修

読まなかったら後悔させる自信があるほど良い資料

読んだ今なら言える。そ れ な !!

ことみんさんについては、こちらの記事がオススメです1

エンジニア基礎の見取り図

扱うのは、「ポータブルスキル」「スタンス・マインド」「ポテンシャル」。
コードは登場しません。
マインドセットが中心です。

上で紹介した、ウィルゲートさんブログにことみんさんが書かれています。

私自身の経験を振り返ると、新卒でエンジニアになってから3年間、技術力を伸ばすことに加えて、成長に必要だったのは正しいスタンスやマインドセットの習得でした。これらの基礎がなければ、いくら技術力があってもそのポテンシャルを最大限に発揮することは難しく、逆に言えば、この基礎があれば技術習得やエンジニアとして成長するスピードもグンと上がります。

7部構成です

  1. ガイダンス
  2. エンジニアとしての基本心構え
  3. コミュニケーションの心構え
  4. キャッチアップスキル
  5. 作業をするとき全般
  6. コードを書くとき全般
  7. 継続的な成長

私のメモ(非公式)として小見出しを入れるとこんな感じ。

  1. ガイダンス
  2. エンジニアとしての基本心構え
    • プロ意識
      • ドメイン知識を正しく理解する
      • 自分のプロダクトに1番詳しい人になる
      • プロダクトの歴史を想像する
    • 仕事をする上で大事な振る舞い
      • 他チームとの連携
      • MTGの目的を理解する
      • 先輩・上司の言っていることの意図を理解する
  3. コミュニケーションの心構え
    • コミュニケーション全般
      • 相手のコンテキストを想像しよう
      • 正しい言葉を使おう
    • テキストコミュニケーション
      • 適切なマークアップを使おう
      • 質問の仕方を意識しよう(質問テンプレート)
    • 質問力
  4. キャッチアップスキル
  5. 作業をするとき全般
    • ツールを使いこなそう
    • times
  6. コードを書くとき全般
    • 認知負荷
      • わかりやすさ(『リーダブルコード』)
    • ベストを尽くす
    • 周辺の機能やロジックも把握して改修する
  7. 継続的な成長
    • ふりかえり

「それな!」と思ったポイント祭り

私に特に刺さったポイント(「それな!」「そうだよなあ、めっちゃいいなあ」)を書き出していきます。
大部なので、「それな!」ポイントは人によって違うんじゃないかな〜。
気になる方は、ぜひ資料本体をご確認ください

コードを書くときはベストを尽くす

6.コードを書くとき全般 より

「後で直せばいいからちょっとだけ手を抜こう」は、すぐ先の未来に跳ね返ってくるんですよね2

あと全力で書いたコードだからこそ、インプットする中でよりよいやり方を知った時に「やらかした〜、悔しい〜〜。次はもっとうまくやりたい」とつながる気がします3

プロ意識

2.エンジニアとしての基本心構え より

成長してレベルの高い仕事をすることを期待されている

Uncle Bobみを感じて、共感します

特に響くのは「1番詳しい人になる」という心構え4
自分が書いたコードから始めて、詳しくなっていくんだ!

質問力とは、わからないことをほっとかない力

3.コミュニケーションの心構え より

ツールを使いこなそう

5.作業をするとき全般 より

目の前の作業よりも、今10分とか30分調べて効率が上がるなら、結果的に良い

このマインドセットはとてもよく、もっと身につけたいと思いました。
「多少力技を使ってでも目の前の作業を終わらせちゃおう」という誘惑がありますが、少し時間がかかってもスマートな解決策を身につける
短期ではなく中長期で見ている!

Slackは即レス・全部見る

4.キャッチアップスキル より

ここは環境によって読み替えが必要かなと思います。
(私は常時ペアプロしているから即レスではないし、全部見るのは諦めました。組織も大きく、常に知らない・見えていないことがあると思っています)

MTG中はMTGに集中しましょう

ながらは生産性を落としますね。
MTGの目的(必要があって呼ばれている)とも矛盾してしまう

「即レス・全部見る」は業務中のマインドセットだと思っています。
BYODの環境でSlackをスマホに入れている場合、注意しないとこいつはプライベートの時間に食い込んできます。
ですが、オンオフの切り替えは重要。
プライベートの時間はリフレッシュに振るべき5と考えています6

新卒時代にプライベートも常時Slackを見る習慣がついてしまって、「休むって何することだっけ」となった経験からの共有でした(その会社でのはからいにより、回復しています)

終わりに

ことみんさんによる「エンジニア基礎」研修資料を読んでのメモでした。
これはあれですね、そーだいさん7並みにいいことしか言ってないですね。
なので、ぜひ一次情報をご確認ください!

めちゃめちゃ蛇足感がありますが、「この大作を読んで共感するけど、これ全部できるようになれるかなあ」という方へ。
マインドセットとは別に、技術の広大な海も広がっていますもんね。

ことみんさんも「毎日、少しずつ意識」「一つひとつ自分をアップデート」と書かれています

私からはこちらを送りましょう。

今できないことがあっても大丈夫。これからできるようになればいいって思います

P.S. 受講の機会キター!

勝ったな!


  1. 読んでの私の感想
  2. t-wadaさんの「質とスピード」を思い出します
  3. 伊藤直也さんのツイート。まさにこれなんです!
  4. 小野和俊さん『その仕事、全部やめてみよう』の「ラストマン戦略」を思い出しました
  5. 温度感の表現が難しくて、スマホの通知は基本切ってますが、自分が一番詳しい領域の通知だけはありにしてます(障害に気づくため)
  6. 「私より技術力のある方を観測すると、皆さん休みの日は趣味でリフレッシュされている」8 あの日シアターデイズをインストールし、長らく封印していた仕掛け人を再開した私へ(ミリシタ新人Pのプレイ録) - nikkie-ftnextの日記
  7. 一例です
  8. 私のリフレッシュは、攻略のための試行錯誤も含まれています。ゲーム感覚なんですよ

『大規模言語モデル入門』8章で文埋め込みの理解を更新。単語埋め込みの平均じゃないんですね!

はじめに

色打掛は花嫁衣装、nikkieです

文埋め込み(文のベクトル)について、理解を更新したメモです

  • 文埋め込み同士の距離は意味の類似度を表す
  • (理解 NEW!!)文埋め込みは特徴量として使える
  • (理解 NEW!!)文埋め込みは、単語埋め込みの平均ではない

目次

文埋め込みの嬉しい点(2点)

紐解いたのは『大規模言語モデル入門』。

第8章が、ズバリ「文埋め込み」です。

文の意味を表現するベクトル(数字の並び)が文埋め込みです。
文埋め込みの嬉しい点(書籍だと目的)は、ベクトルの距離が文の意味的類似度を表す点。
意味が似ている文のベクトル同士は距離が近く、似ていない文のベクトル同士は距離が遠くなります。

以前触った記事がこちら

今回もう1つ嬉しい点があることを知りました。
文埋め込みは特徴量として使えるんです!

文埋め込みによって得られたベクトルを特徴量として用いることで、多層パーセプトロンのような単純なモデルでも下流タスクを解く (Kindle版 p.406)

OpenAI1のCookbook中に、文埋め込みを特徴量として、random forestで分類する例があります。

単語のベクトルの平均だと誤解していた

埋め込みは文のレベルだけでなく、文を構成する単語レベルでも得られます。
代表的な手法はword2vec2

文を構成する単語の埋め込みを平均3したら、文の埋め込みになると思っていたのですが、これは誤解でした。

文中の単語の順序や、文脈によって決まる単語の意味を考慮できない (Kindle版 p.411)

見事な例だなと思ったのがこちら

  • 会社の音楽を再生する
  • 音楽の会社を再生する

この2文、構成する単語は同じですよね。
「会社」と「音楽」が入れ替わっているだけです。
ですが、2文の意味は異なります。
「再生」の意味が違うんですよね。

この例で単語の埋め込みの平均を考えると、構成する単語が同じなので、同じベクトルになります。
同じベクトルというのは、構成する単語が同じだが2文の意味は異なるという私たちの感覚を反映できていませんね。

というわけで、単語の埋め込みの平均ではないと理解を改めました。

なお、BERTの出力も文埋め込みに向かない(あまり性能が高くない)と解説されています。

今後:どう作られるかを知りたい

『大規模言語モデル入門』では、SimCSEという文埋め込みモデルの訓練(対照学習)が解説されます4(宿題事項)。
https://github.com/ghmagazine/llm-book/blob/4990a3e69effd794847a6240b8386d3073d78ed4/chapter8/8-3-simcse-training.ipynb

SimCSE自体は聞いたことがありました(積ん読5

教師なしの文類似度タスクの場合、BERTを使って単語をベクトルに変換し、そのベクトルの平均を文のベクトルとするよりも、GloVeなどの単語ベクトルを使用して単語をベクトルに変換した方が良い

しかし、今回ご紹介するSimCSEを使うことで、従来の教師ありによる文ベクトルと同等の性能を発揮することが可能です。また、この論文の優れている点として、BERTを使用した場合に精度が悪化する原因まで明らかにした点があります。

SimCSE(対照学習)の先にOpenAIの埋め込み用APIがあると思うのですが、OpenAIが出しているこちらの論文も気になるところです。

ada-002のブログにて、比較対象の旧モデルとしてこの論文を見つけました。
New and improved embedding model



  1. embedding(埋め込み)を得られるAPIがいくつかありますね。
  2. 過去にこんなことをしました。
  3. 『大規模言語モデル入門』によると、ベースラインとしては有力とのことです(8.1.4)
  4. 8章はembeddingsの他にFaissも扱うので、RAGの要素技術が詰まった章だな〜と思います。
  5. こちらの記事、sentence-transformersに言及しており、こちらとつながりが見えた気がします。