多言語対応Embedding Model、Snowflake Arctic Embed L 2.0およびM 2.0が登場！

この記事は[Snowflake Advent Calendar 2024](https://qiita.com/advent-calendar/2024/snowflake)の10日目です。
みんなでAIデータクラウドの世界を盛り上げていきましょう！

## Snowfalke ArcticとそのEmbedding Model

Snowflake ArcticはSnowflake社が開発した大規模言語モデル(LLM)です。  
Apache 2.0ライセンスで提供されています。  
また、文章を生成するLLMだけではなく、Embedding Modelも存在します。  

Embedding Modelとは、テキストなどのデータを高次元ベクトル表現に変換することに特化したモデルで、これを活用することでデータを意味的な類似性で検索することができるようになるため、例えばRAG(Retrieval-Augmented Generation)などで活用されています。  
…というEmbedding Modelについて、これまでSnowflake社が公開していたものは英語のみに対応した[Snowflake Arctic Embed M v1.5](https://www.snowflake.com/engineering-blog/arctic-embed-m-v1-5-enterprise-retrieval/)だったのですが、2024/12/4に多言語に対応した[Snowflake Arctic Embed L 2.0およびM 2.0](https://www.snowflake.com/engineering-blog/snowflake-arctic-embed-2-multilingual/)がリリースされました！  

https://www.snowflake.com/engineering-blog/snowflake-arctic-embed-2-multilingual/

ちなみに多言語に対応していないEmbedding Modelを使って日本語の文章を高次元ベクトル表現に変換すると、同じような意味合いの文章なのに全然違うベクトルになったり、全然違う意味合いの文章なのに同じようなベクトルになったりするせいで、上手く検索できません。悲しい。  

## Google Colabで試してみよう

[ここ](https://docs.snowflake.com/en/sql-reference/functions/embed_text-snowflake-cortex)や[ここ](https://docs.snowflake.com/en/sql-reference/functions/embed_text_1024-snowflake-cortex)のドキュメントを見る限りではまだSnowflakeにはデプロイされていないようなので(2024/12/10時点)、  
[Hugging Faceで公開されているモデル](https://huggingface.co/Snowflake/snowflake-arctic-embed-m-v2.0)を使ってGoogle Colab (Colaboratory)で試してみましょう。  

https://huggingface.co/Snowflake/snowflake-arctic-embed-m-v2.0

試したソースコードは[こちら](https://github.com/Sakatoku/vector-search-with-duckdb/blob/main/using_snowflake_arctic_embed_m_v2_0.ipynb)、試したデータは[こちら](https://github.com/Sakatoku/vector-search-with-duckdb/blob/main/philosopher_detail.csv)です。

まず、ノートブックを作成して、ランタイムのタイプを```T4 GPU```に変更します。  

![Setting](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/f60fe03e-dce0-d330-0f38-7df7ad717e17.png)

適当にデータを読み込んで、  

```py
import pandas as pd
df = pd.read_csv('/content/philosopher_detail.csv')
print(df)
```

```SentenceTransformers```と```xformers```をインストールします。  

```sh
!pip install sentence_transformers xformers
```

```Snowflake/snowflake-arctic-embed-m-v2.0```モデルをダウンロードして試しに実行してみます。  
```sentences```の3つの文章をEmbeddingしてくれました。  

```py
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("Snowflake/snowflake-arctic-embed-m-v2.0", trust_remote_code=True)

sentences = [
    "The weather is lovely today.",
    "It's so sunny outside!",
    "He drove to the stadium."
]
embeddings = model.encode(sentences)
print(embeddings)
```

![Test Embedding](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/e2ab8b47-d68e-0569-91b5-f89e478a477c.png)

読み込んだデータから日本語の文章をEmbeddingしてみましょう。  

```py
embeded_biographies = model.encode(df["BIOGRAPHY"])
```

これだけだと「たくさん数字が出てきたなー」だけなので、比較する文章もEmbeddingしてみます。  
```query1```は元のデータに含まれるヒポクラテスの説明を英語に翻訳したものです。正しく多言語対応していれば、日本語でも英語でも近い値のベクトルになるはずです。  
また、```query2```はRAG的な使い方を想定した質問文形式の文章です。ベクトルにしたときにこの質問のベクトルと近い値になる文章を元のデータから取得してソースとしてLLMに与えるのがRAGですね。  

```py
query1 = "HippocratesHippocrates was an ancient Greek physician and is often referred to as the Father of Western Medicine. His achievements laid the foundation for a scientific approach in the field of medicine. Hippocrates attributed the causes of diseases not to supernatural forces or natural phenomena but to dysfunctions within the body and environmental factors, emphasizing observation and experimentation. His work, Corpus Hippocraticum, is a comprehensive compilation of ancient Greek medical knowledge and has significantly influenced later medical practices. The Hippocratic Oath, which outlines the ethical principles for physicians, continues to be highly respected in the medical field today."
embeded_query1 =  model.encode(query1)
query2 = "プラグマティズムの提唱者は？"
embeded_query2 =  model.encode(query2)
```

Embeddingした結果を比較して、一番近いものを抜粋してみます。  

```py
import torch

# query1と一番類似しているもの
similarities = model.similarity(embeded_biographies, embeded_query1)
idx = int(torch.argmax(similarities, dim=0)[0])
print(f"クエリ: {query1}")
print(f"類似度: {similarities[idx]}")
print(f"前後の行の類似度: {similarities[idx-1]}, {similarities[idx+1]}")
print(df[idx:idx+1])

# query2と一番類似しているもの
similarities = model.similarity(embeded_biographies, embeded_query2)
idx = int(torch.argmax(similarities, dim=0)[0])
print(f"クエリ: {query2}")
print(f"類似度: {similarities[idx]}")
print(f"前後の行の類似度: {similarities[idx-1]}, {similarities[idx+1]}")
print(df[idx:idx+1])
```

![Result](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2917580/fc40e4cb-d672-2114-381e-5c7e7be7b0a1.png)

```query1```については、一番高い類似度が0.6441になりました。
以下の文章と一番類似しているということなので、バッチリ想定通り！  

> \<name>ヒポクラテス\</name>\<detail>ヒポクラテスは、古代ギリシャの医師であり、西洋医学の父と呼ばれる人物です。彼の業績は、医学の分野における科学的アプローチの基礎を築いたことです。ヒポクラテスは、病気の原因を自然現象や超自然的な力ではなく、身体の機能の不調や環境要因に求め、観察と実験を重視しました。彼の著作「ヒポクラテス全集」は、古代ギリシャ医学の集大成であり、後世の医学に大きな影響を与えました。ヒポクラテスの誓いは、医師の倫理的原則を示すものとして、現在も医療界で尊重されています。\</detail>

```query2```については、一番高い類似度が0.5348になりました。  
```query1```は言語が違うだけで同じ意味の文章なので、それと比べると低くなっていますね。  
以下の文章と一番類似しているということです。  

> \<name>チャールズ・サンダース・パース\</name>\<detail>プラグマティズムの提唱者の一人。プラグマティズムは、真理は実践的有用性に基づくという考え方である。パースは、真理は実験と観察を通じて検証されるべきであると主張し、科学的方法の重要性を強調した。また、記号論の分野でも重要な貢献をし、記号の概念を研究した。\</detail>

## まとめ

今回はM 2.0を使って基本的なEmbeddingのみを試しましたが、Snowflake Arctic Embed L 2.0だと  

- 高速
- 英語と英語以外のいずれでもベンチマークスコアが高い
- ベクトルを圧縮しても品質が劣化しにくい

などの特徴があるそうです。  
これまでSnowflakeのLLM周りは多言語対応がちょっと弱かったのですが、これからがすごく楽しみになるリリースでした！