LangChainでHugging Faceに公開されている日本語版 Gemma 2 2Bを使用する方法

:::note warn
この投稿は、検証結果を記載したメモ書きをもとに、[Claude.ai](https://claude.ai/)で生成した文章です。

メモ書き投稿はこちらです。（限定共有記事として公開しています）

[Hugging FaceのモデルをLangChainで使う（メモ書き）](https://qiita.com/moritalous/private/b73b9bb4b19be4ea2244)

Claude.aiには、メモ書きのMarkdownを添付し、 **「ブログ記事の下書きを作成しました。説明が不足していると感じているので、補完してください。」** と依頼しました。

生成AIでの文章生成の雰囲気を体験してもらえたらと思い、Claude.aiの出力をそのまま掲載します。

以下の点のみ、手作業で修正しました。

* 注釈部分を追記
* タイトルが「SageMakerでGemmaモデルを使用する方法」でしたので修正
:::


## はじめに

この記事では、Amazon SageMakerを使用してGoogleのGemmaモデルをセットアップし、LangChainと統合する方法を紹介します。Gemmaは最近リリースされた強力な言語モデルで、日本語での処理も可能です。

:::note warn
検証したのはGemmaではなく、[日本語版 Gemma 2 2B](https://developers-jp.googleblog.com/2024/10/gemma-2-for-japan.html)です。
:::

## 環境セットアップ

まず、SageMakerのインスタンスタイプ `ml.g4dn.2xlarge` を使用します。このインスタンスは、機械学習タスクに適した性能を持っています。

### Condaの初期化

SageMakerのターミナルで以下のコマンドを実行し、Conda環境をセットアップします：

```shell
conda init
source ~/.bashrc 
conda create --name langchain-hf -y
conda activate langchain-hf
conda install pip ipykernel ipywidgets -y
export CURRENT_ENV_NAME=$(conda info | grep "active environment" | cut -d : -f 2 | tr -d ' ')
python3 -m ipykernel install --user --name $CURRENT_ENV_NAME --display-name "user-env:($CURRENT_ENV_NAME)"
```

これらのコマンドは新しいConda環境を作成し、必要なパッケージをインストールします。

### 必要なライブラリのインストール

ブラウザをリロードした後、Jupyter Notebookで以下のコマンドを実行して必要なライブラリをインストールします：

```python
%conda install -y accelerate pytorch transformers huggingface_hub pytorch-cuda=12.4 -c pytorch -c nvidia
%pip install langchain langchain-huggingface
```

これにより、PyTorch、Transformers、LangChainなどの重要なライブラリがインストールされます。

## Hugging Faceへのログイン

Hugging Faceの機能を使用するために、アカウントにログインします：

```python
from huggingface_hub import login
login()
```

表示されるプロンプトにHugging Faceのトークンを入力してください。

:::note warn

<details><summary>画面キャプチャ</summary>

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/dc6e29d1-8ce2-7503-32e0-2aeab9a66ffa.png)

</details>

:::

## Gemmaモデルのセットアップ

次に、Gemmaモデルをセットアップします：

```python
import torch
from langchain_huggingface.llms import HuggingFacePipeline

llm = HuggingFacePipeline.from_model_id(
    model_id="google/gemma-2-2b-jpn-it",
    task="text-generation",
    pipeline_kwargs={"max_new_tokens": 2048},
    model_kwargs={"torch_dtype": torch.bfloat16},
    device=0, # -1 for CPU
)
```

このコードは、日本語ITドメイン向けにファインチューニングされたGemma 2B モデルをロードします。

:::note warn
「日本語ITドメイン向け」はおそらくモデル名から推測したものと思われます。
itはInstruction Tuningの略ですね。
:::

## モデルの使用

モデルを使って簡単な質問に答えてみましょう：

```python
llm.invoke("日本について知っていることを教えて下さい。")
```

:::note warn

<details><summary>出力結果</summary>

> '日本について知っていることを教えて下さい。\n\n基本的な情報\n\n* 国名: 日本\n* 首都: 東京\n* 国旗: 赤と白の旗\n* 国土: 約377,975平方キロメートル\n* 人口: 約1億2,400万人\n* 言語: 日本語\n* 通貨: 日本円\n\n歴史・文化\n\n* 歴史: 古代から近代まで、長い歴史を持つ\n* 文化: 伝統的な文化、芸術、音楽、食文化など、多様性と奥深さがある\n* 伝統文化: 茶道、書道、歌舞伎など、世界的に有名な伝統文化がある\n* 芸術: 日本の芸術は、絵画、彫刻、陶芸など、世界的に高い評価を得ている\n\n経済・社会\n\n* 経済: 世界第3位の経済規模を持つ\n* 社会: 高度な社会制度を持つ\n* 教育: 世界トップレベルの教育制度を持つ\n\n自然\n\n* 自然: 山、海、湖など、豊かな自然環境を持つ\n* 気候: 四季折々の気候\n* 観光地: 富士山、京都、大阪など、世界的に有名な観光地がある\n\n\n \n\n\n \n'

</details>

:::

この呼び出しにより、日本に関する基本的な情報が返されます。

## チャットモデルの使用

LangChainのチャットモデルを使用する場合は以下のようにします：

```python
chat = ChatHuggingFace(llm=llm)
chat.invoke("日本について知っていることを教えて下さい。")
```

:::note warn

<details><summary>出力結果</summary>

> AIMessage(content='user\n日本について知っていることを教えて下さい。\nmodel\n## 日本について知りたいこと、教えてください！😊\n\n日本について、どんなことを知りたいですか？\n\n例えば…\n\n歴史・文化方面:\n\n* 日本の歴史について知りたい\n* 日本の伝統文化について知りたい\n* 日本の芸術や文化について知りたい\n* 日本の伝統芸能について知りたい\n* 日本の宗教について知りたい\n\n地理・自然方面:\n\n* 日本の地理について知りたい\n* 日本の気候について知りたい\n* 日本の自然景観について知りたい\n* 日本の山岳地帯について知りたい\n* 日本の海について知りたい\n\n経済・社会方面:\n\n* 日本の経済について知りたい\n* 日本の社会制度について知りたい\n* 日本の教育制度について知りたい\n* 日本の生活習慣について知りたい\n* 日本の政治について知りたい\n\nその他:\n\n* 日本のアニメや漫画について知りたい\n* 日本の食べ物について知りたい\n* 日本のファッションについて知りたい\n* 日本の音楽について知りたい\n* 日本の映画について知りたい\n\n\n\n \n \n \n\n\n \n', additional_kwargs={}, response_metadata={}, id='run-6a563ad3-7e87-4a8c-92dc-6a8d9f50ae62-0')

</details>

:::

応答からトークンの区切り文字を削除するには、`skip_prompt=True`を指定します：

```python
chat2 = chat.bind(skip_prompt=True)
chat2.invoke("日本について知っていることを教えて下さい。")
```

:::note warn

<details><summary>出力結果</summary>

> AIMessage(content='## 日本について知りたいこと、教えてください！😊\n\n日本について、どんなことを知りたいですか？\n\n例えば…\n\n歴史・文化方面:\n\n* 日本の歴史について知りたい\n* 日本の伝統文化について知りたい\n* 日本の芸術や文化について知りたい\n* 日本の伝統芸能について知りたい\n* 日本の宗教について知りたい\n\n地理・自然方面:\n\n* 日本の地理について知りたい\n* 日本の気候について知りたい\n* 日本の自然景観について知りたい\n* 日本の山岳地帯について知りたい\n* 日本の海について知りたい\n\n経済・社会方面:\n\n* 日本の経済について知りたい\n* 日本の社会制度について知りたい\n* 日本の教育制度について知りたい\n* 日本の生活習慣について知りたい\n* 日本の政治について知りたい\n\nその他:\n\n* 日本のアニメや漫画について知りたい\n* 日本の食べ物について知りたい\n* 日本のファッションについて知りたい\n* 日本の音楽について知りたい\n* 日本の映画について知りたい\n\n\n\n \n \n \n\n\n \n', additional_kwargs={}, response_metadata={}, id='run-cbb7c55f-ab4c-4805-9d7f-a33532a10630-0')

</details>

:::

## ストリーミング応答

:::note warn
検証した限り、うまく動作しないと思います
:::

モデルからストリーミング応答を取得するには：

```python
for chunk in chat2.stream("日本の文化や歴史について長文で回答してください。"):
    print(chunk)
```

注意：このモデルでは、応答が1つのチャンクとして返される場合があります。

## 追加のツールの統合

:::note warn
検証した限り、うまく動作しないと思います
:::

LangChainを使用して追加のツールを統合することもできます。例えば、DuckDuckGoの検索結果を使用する場合：

```python
%pip install -qU duckduckgo-search langchain-community

from langchain_community.tools import DuckDuckGoSearchResults

search = DuckDuckGoSearchResults()

chat3 = chat2.bind_tools([search]).bind(skip_prompt=True)
chat3.invoke("Webで Amazon を検索してください")
```

ただし、現在のセットアップではこの統合が正常に機能しない可能性があります。

## まとめ

このチュートリアルでは、Amazon SageMakerを使用してGoogleのGemmaモデルをセットアップし、LangChainと統合する方法を紹介しました。これにより、強力な言語モデルを使用して様々なNLPタスクを実行できるようになります。


:::note warn

生成AIの出力結果はいかがでしたか？当たり障りのない感じではありますが、事前な文章だと感じます。

生成AIの出力結果をもとに手直しをすることで、効率的に良い記事がアウトプットできるので、みなさんも試してみてはいかがでしょうか？

（検証は自分の手を動かすのが大事と思います😝）
:::