見出し画像

Feature Stores and LLMs

Feature Storeで管理されている特徴量をそのままプロンプトに突っ込んだらパーソナライズされたユーザー体験に役立つんじゃない?という感じのブログ記事がLangChain公式にあって面白いなと思ったのでまとめてみました。

Feature Storeって何?という方はこのあたりのブログ記事をご参考に。

なぜFeature Storeが役に立つのか?

Feature Storeとはざっくり「機械学習モデルで扱う特徴量をひとまとめに管理する基盤」のこと。特徴量のソースとなるデータレイクがバラバラだったり、学習時と推論時でモデルに入力する特徴量の参照先が異なるといった事情があったりといった、機械学習モデルにおける特徴量運用の問題を解決するために存在している。

https://www.tecton.ai/blog/what-is-a-feature-store/

このような役割上、Feature Storeは様々なデータによってリアルタイムに特徴量を更新する特徴量のリアルタイムパイプラインとも言える。

GPTのようなLLMのコンテキストサイズには限りがある(GPT-3.5で4096トークン)ので、より濃縮された、LLMによるアウトプットを適切に左右するようなデータをプロンプトに投入することがカギになる。

特徴量とはそのまま何らかの特徴を表した値と言えるわけで、であれば特徴量そのものを濃縮されたインプットデータとして上手く利用できるのではないか、というのがブログ記事での提案である(と、私は読み取った)。

コード実例

LangChainのドキュメントにfeastというOSSのFeature Storeと連携させてみたコード例が掲載されている。

コードの雰囲気はこんな感じになる。

まずFeatureStoreを初期化する。既にリポジトリに何らかのデータが入っていることが前提となる。

from feast import FeatureStore

store = FeatureStore(repo_path='./feature_repo/')

次にプロンプトを定義する。

from langchain.prompts import PromptTemplate, StringPromptTemplate

template = """Given the driver's up to date stats, write them note relaying those stats to them.
If they have a conversation rate above .5, give them a compliment. Otherwise, make a silly joke about chickens at the end to make them feel better

Here are the drivers stats:
Conversation rate: {conv_rate}
Acceptance rate: {acc_rate}
Average Daily Trips: {avg_daily_trips}

Your response:"""
prompt = PromptTemplate.from_template(template)

ドライバーの最新のステータスがわかったら、そのステータスを伝えるメモを書きます。会話率が0.5以上であれば褒めてあげてください。そうでない場合は、最後にニワトリに関するくだらないジョークを言ってドライバーの気分を良くさせてください。

以下がドライバーの統計データです:
会話率: {conv_rate}
受入率: {acc_rate}
1日の平均トリップ数: {avg_daily_trips}

レスポンス:

プロンプト日本語訳

サンプルコードではドライバーIDを引数にして、このプロンプト内の統計データの各値に自動的に特徴量を埋め込むようなラッパーを作成している。

class FeastPromptTemplate(StringPromptTemplate):
    
    def format(self, **kwargs) -> str:
        driver_id = kwargs.pop("driver_id")
        feature_vector = store.get_online_features(
            features=[
                'driver_hourly_stats:conv_rate',
                'driver_hourly_stats:acc_rate',
                'driver_hourly_stats:avg_daily_trips'
            ],
            entity_rows=[{"driver_id": driver_id}]
        ).to_dict()
        kwargs["conv_rate"] = feature_vector["conv_rate"][0]
        kwargs["acc_rate"] = feature_vector["acc_rate"][0]
        kwargs["avg_daily_trips"] = feature_vector["avg_daily_trips"][0]
        return prompt.format(**kwargs)

実行結果はこんな感じになる。

prompt_template = FeastPromptTemplate(input_variables=["driver_id"])
print(prompt_template.format(driver_id=1001))

Given the driver's up to date stats, write them note relaying those stats to them.
If they have a conversation rate above .5, give them a compliment. Otherwise, make a silly joke about chickens at the end to make them feel better

Here are the drivers stats:
Conversation rate: 0.4745151400566101
Acceptance rate: 0.055561766028404236
Average Daily Trips: 936

Your response:

このプロンプトを元に推論を実行すると、こんな結果が得られる。

Hi there! I wanted to update you on your current stats. Your acceptance rate is 0.055561766028404236 and your average daily trips are 936. While your conversation rate is currently 0.4745151400566101, I have no doubt that with a little extra effort, you'll be able to exceed that .5 mark! Keep up the great work! And remember, even chickens can't always cross the road, but they still give it their best shot.

日本語訳
こんにちは!あなたの現在の統計情報をお知らせします。あなたの受入率は0.055561766028404236で、1日の平均トリップ回数は936回です。会話率は0.4745151400566101ですが、もう少し努力すれば0.5を超えられると信じています!これからも頑張ってください!そして、ニワトリだって、いつも道を渡れるわけではないのですが、それでも頑張っていることを忘れないでください。

所感

例のようなメッセージ通知的な使い方だとあまり面白くない感じがしたのですが、例えばシステムメッセージに特徴量を反映するようにしておいて、会話率が低い場合は会話のネタになりそうなことをアドバイスするようにしておくとか、忙しそうな人には端的なメッセージに留めるようにするとか、そんなパーソナライズの方向性はあるんじゃないかなと感じました。

わざわざFeature StoreとLLMを使うかどうかはさておきですが、特徴量をソースにして「このユーザーが使いそうな機能」へのショートカットリンクをLLMで選定してユーザーにサジェストするのも面白そうだなと感じました。関心の高そうなタグを選出するとか。

機械学習の基盤も人的リソースもない組織ではこのようなサジェスト機能一つ作ることに対してですらもかなりの心理的/運用的ハードルがありましたが、質の高いLLMの利用コストが小さくなったことで「精度は知らんがとりあえずやってみる」ことができるようになったのは大きな変化だなと感じます。

現場からは以上です。

この記事が気に入ったらサポートをしてみませんか?