Azure AI Studio のモデルカタログに Cohere-rerank-v3-multilingual が登場

[Azure AI Studio](https://ai.azure.com/) のモデルカタログに Cohere 社のリランクモデルである [Cohere-rerank-v3-multilingual](https://ai.azure.com/explore/models/Cohere-rerank-v3-multilingual/version/1/registry/azureml-cohere) と [Cohere-rerank-v3-english](https://ai.azure.com/explore/models/Cohere-rerank-v3-english/version/1/registry/azureml-cohere) が登場しました。Azure AI Studio では、リランクモデルを**サーバーレス API として従量課金で利用**できます。ユーザーは GPU インスタンスの心配をする必要はありません。

- 料金: $2.00 per 1000 queries
- コンテキスト ウィンドウ: 4,096 トークン
- クエリの最大長: 2,048 トークン
- multilingual は 100 以上の言語に対応、もちろん日本語対応
- リージョン: 米国東部, 米国東部 2, 米国中北部, 米国中南部, 米国西部, 米国西部 3, スウェーデン中部

>Rerank Multilingual は、Miracl などの多言語ベンチマークで優れたパフォーマンスを発揮します。([benchmark](https://github.com/cohere-ai/notebooks/blob/main/public_rerank_benchmarks/miracl.md)）


# Azure AI Studio
Azure AI Studio のモデルカタログから数秒デプロイ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/2cacc6b9-087a-2268-ff06-b6a7fe372e1a.png)

https://learn.microsoft.com/azure/ai-studio/how-to/deploy-models-cohere-rerank

# Cohere SDK
`cohere==5.6.2` で実行。
```python
import cohere

co = cohere.Client(
    base_url="https://<Name>.<Region>.models.ai.azure.com/v1", 
    api_key=""
)
```

`base_url` の表記に注意。Azure AI Studio の ターゲット URI をコピペしてもダメだし API ルートを使ってもダメ。`/v1` で止める必要があります。
 

```python
documents = [
    {
        "Title": "源頼朝が鎌倉幕府を開くまでの経緯はどのようなものですか？",
        "Content": "源頼朝は平治の乱（1159年）で敗れた後、伊豆国に配流されていました。しかし、1180年に以仁王（もちひとおう）の令旨を受け、平氏打倒の挙兵を決意しました。その後、各地の武士を味方につけ、1185年に平氏を壇ノ浦で滅ぼし、1192年に征夷大将軍に任命されて鎌倉幕府を開きました。",
    },
    {
        "Title": "源義経はなぜ兄の源頼朝に追われることになったのですか？",
        "Content": "源義経は、兄源頼朝のために多大な功績をあげましたが、頼朝との間に不和が生じました。義経が後白河法皇に厚遇されたことや、頼朝の許可なく官位を受けたことが頼朝の怒りを買い、最終的に追討命令が出されました。義経は各地を逃亡しましたが、最終的に奥州藤原氏の元で自害しました。この出来事は日本史の中でも特に悲劇的なエピソードとして知られています。",
    },
    {
        "Title": "源平合戦とは何ですか？",
        "Content": "源平合戦は、平安時代末期に源氏と平氏の間で行われた一連の戦いの総称です。1180年から1185年まで続いたこの戦争の結果、源氏が平氏を滅ぼし、源頼朝が鎌倉幕府を開くきっかけとなりました。特に有名な戦いは1185年の壇ノ浦の戦いで、これにより平氏は滅亡しました。",
    },
    {
        "Title": "源実朝とは誰ですか？",
        "Content": "源実朝（1192年-1219年）は、鎌倉幕府の第3代将軍です。源頼朝の次男で、頼朝の死後に兄の源頼家が2代将軍となりましたが、頼家が失脚した後、実朝が将軍の座に就きました。彼は文化的・文学的な才能にも恵まれ、特に和歌において優れた作品を残しています。",
    },
    {
        "Title": "源実朝はどのようにして命を落としましたか？",
        "Content": "源実朝は1219年、鶴岡八幡宮での右大臣拝賀の儀式の帰途、甥の公暁（くぎょう）によって暗殺されました。公暁は、兄の源頼家の子供であり、実朝の将軍職に不満を持っていたとされます。この暗殺により、源氏の直系は絶えることとなり、鎌倉幕府における源氏の時代は終焉を迎えました。",
    }
]

response = co.rerank(
    documents=documents,
    query="源実朝の趣味はなんですか？",
    rank_fields=["Title", "Content"],
    top_n=5,
    return_documents=True
)

for doc in response.results:
    print(f"index: {doc.index}, relevance_score: {doc.relevance_score}")
    print(doc.document.Content)
```

`rank_fields` でランク付けするフィールドを[指定できます](https://learn.microsoft.com/azure/ai-studio/how-to/deploy-models-cohere-rerank#v1rerank-request-schema)。さらに渡されたフィールドの順序に基づいてリランクされます。

## リランク結果
さすがです。日本語で欲しい結果が 1 位にリランクされました。
```yml
index: 3, relevance_score: 0.52366394
源実朝（1192年-1219年）は、鎌倉幕府の第3代将軍です。源頼朝の次男で、頼朝の死後に兄の源頼家が2代将軍となりましたが、頼家が失脚した後、実朝が将軍の座に就きました。彼は文化的・文学的な才能にも恵まれ、特に和歌において優れた作品を残しています。
index: 4, relevance_score: 0.027324531
源実朝は1219年、鶴岡八幡宮での右大臣拝賀の儀式の帰途、甥の公暁（くぎょう）によって暗殺されました。公暁は、兄の源頼家の子供であり、実朝の将軍職に不満を持っていたとされます。この暗殺により、源氏の直系は絶えることとなり、鎌倉幕府における源氏の時代は終焉を迎えました。
index: 0, relevance_score: 7.905304e-05
源頼朝は平治の乱（1159年）で敗れた後、伊豆国に配流されていました。しかし、1180年に以仁王（もちひとおう）の令旨を受け、平氏打倒の挙兵を決意しました。その後、各地の武士を味方につけ、1185年に平氏を壇ノ浦で滅ぼし、1192年に征夷大将軍に任命されて鎌倉幕府を開きました。
index: 1, relevance_score: 8.664653e-06
源義経は、兄源頼朝のために多大な功績をあげましたが、頼朝との間に不和が生じました。義経が後白河法皇に厚遇されたことや、頼朝の許可なく官位を受けたことが頼朝の怒りを買い、最終的に追討命令が出されました。義経は各地を逃亡しましたが、最終的に奥州藤原氏の元で自害しました。この出来事は日本史の中でも特に悲劇的なエピソードとして知られています。
index: 2, relevance_score: 4.710909e-06
源平合戦は、平安時代末期に源氏と平氏の間で行われた一連の戦いの総称です。1180年から1185年まで続いたこの戦争の結果、源氏が平氏を滅ぼし、源頼朝が鎌倉幕府を開くきっかけとなりました。特に有名な戦いは1185年の壇ノ浦の戦いで、これにより平氏は滅亡しました。
```

関連性スコア `relevance_score` は [0, 1] の範囲になるように[正規化されます](https://learn.microsoft.com/azure/ai-studio/how-to/deploy-models-cohere-rerank#v1rerank-response-schema)。スコアが 1 に近いほどクエリとの関連性が高く、0 に近いほど関連性が低いことを示します。

## 英語クエリー→日本語ドキュメント
```python
query="What year was the battle of Dannoura?",
```

```yml
index: 2, relevance_score: 0.94458723
源平合戦は、平安時代末期に源氏と平氏の間で行われた一連の戦いの総称です。1180年から1185年まで続いたこの戦争の結果、源氏が平氏を滅ぼし、源頼朝が鎌倉幕府を開くきっかけとなりました。特に有名な戦いは1185年の壇ノ浦の戦いで、これにより平氏は滅亡しました。
index: 0, relevance_score: 0.38954654
源頼朝は平治の乱（1159年）で敗れた後、伊豆国に配流されていました。しかし、1180年に以仁王（もちひとおう）の令旨を受け、平氏打倒の挙兵を決意しました。その後、各地の武士を味方につけ、1185年に平氏を壇ノ浦で滅ぼし、1192年に征夷大将軍に任命されて鎌倉幕府を開きました。
index: 3, relevance_score: 0.000117744596
源実朝（1192年-1219年）は、鎌倉幕府の第3代将軍です。源頼朝の次男で、頼朝の死後に兄の源頼家が2代将軍となりましたが、頼家が失脚した後、実朝が将軍の座に就きました。彼は文化的・文学的な才能にも恵まれ、特に和歌において優れた作品を残しています。
index: 4, relevance_score: 8.220189e-05
源実朝は1219年、鶴岡八幡宮での右大臣拝賀の儀式の帰途、甥の公暁によって暗殺されました。公暁は、兄の源頼家の子供であり、実朝の将軍職に不満を持っていたとされます。この暗殺により、源氏の直系は絶えることとなり、鎌倉幕府における源氏の時代は終焉を迎えました。
index: 1, relevance_score: 8.398072e-06
源義経は、兄源頼朝のために多大な功績をあげましたが、頼朝との間に不和が生じました。義経が後白河法皇に厚遇されたことや、頼朝の許可なく官位を受けたことが頼朝の怒りを買い、最終的に追討命令が出されました。義経は各地を逃亡しましたが、最終的に奥州藤原氏の元で自害しました。この出来事は日本史の中でも特に悲劇的なエピソードとして知られています。
```

上位の 2 件とも「1185 年壇ノ浦」を含む正解。その逆の日本語クエリー→英語ドキュメントも検証したいですね。

# Azure AI Search 統合例
大規模検索エンジンとの統合が最も良い利用例でしょう。Azure AI Search には組み込みで[セマンティックランカー](https://learn.microsoft.com/azure/search/semantic-search-overview)によるリランク機能が既にありますから、Cohere Rerank の登場によってユーザーの選択肢と組み合わせパターンが増えますね。

```python
def search_vector_query(query, top):
    search_result_ids = []

    search_client = SearchClient(service_endpoint, index_name, credential=credential)
    vector_query = VectorizedQuery(vector=generate_embeddings(query), k_nearest_neighbors=top, fields=vector_field)

    docs = search_client.search(
        search_text=query,
        vector_queries= [vector_query],
        search_fields=["text"],
        select=["text,docid"],
        top=top
    ) 

    for doc in docs:
        search_result_ids.append({"docid": doc['docid'], "text": doc['text']})

    print("Search result ids: ", search_result_ids)
    return search_result_ids

def rerank_search_results(search_result_ids, query, top):
    response = co.rerank(
        documents=search_result_ids,
        query=query,
        rank_fields=["text"],
        top_n=top,
        return_documents=True
    )

    reranked_search_results = []

    for doc in response.results:
        print(f"index: {doc.index}, relevance_score: {doc.relevance_score}, docid: {doc.document.docid}")
        reranked_search_results.add(doc.document.docid)

    return reranked_search_results
```

# 精度比較
[以前](https://qiita.com/nohanaga/items/e159712acbf80e40ca1a#%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB%E6%A4%9C%E7%B4%A2%E3%81%AE%E7%B2%BE%E5%BA%A6%E8%A9%95%E4%BE%A1)作成した MIRACL 日本語データセット `text-embedding-3-small`の結果をリランクすると Recall は全てで上昇しました。`text-embedding-3-large` については一部で上回りましたが、そうでない場合もあるので全部が全部上回るというわけではありませんでした。リランク前の検索条件や使用するデータセット、モデルでそれぞれ検証が必要です。

| | v3-small|v3-small+rerank| v3-large|v3-large+rerank
|:-:|:-:|:-:|:-:|:-:
|#1 Recall@3 avg|0.562|0.666|**0.702**|0.676|
|#1 Recall@5 avg|0.723|0.860|0.813|**0.870**|
|#2 Recall@3 avg|0.594|**0.722**|0.716|**0.722**|
|#2 Recall@5 avg|0.657|0.792|**0.815**|0.812|

`text-embedding-3-small` / `text-embedding-3-large` で 上位 50 件を取得し、これを Cohere-rerank-v3-multilingual モデルの入力とした。`rank_fields` は `text` フィールドのみ。