初心者でもわかる！Hugging Faceを使いこなして、RAG風プロンプトエンジニアリングで精度UPする方法

# Hugging Faceとは
自然言語処理（NLP）や機械学習（ML）に関するプラットフォームです。トレーニング済みモデルが公開されているので、ここから簡単にダウンロードして使用できます。

https://huggingface.co/

こんなことを言っていいのかわからないけれど、見た目が胡散臭いのよ。
![スクリーンショット 2024-09-25 13.31.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846404/7c3792c7-7c82-db34-e4f4-ba1d347fc8ed.png)

## この記事で出来るようになること
Meta社の作成したLlama3モデルを用いて、テキスト生成ができるようになります。
技術の発展が目覚ましいのであれですが、Llama3は日本語においても高い性能を持つモデルの１つです。

# 事前準備（アカウント作成まで）
## Meta社のサイトからLlama3の利用申請
下記のMeta社のサイトから申請を行います。

https://ai.meta.com/resources/models-and-libraries/llama-downloads/

必要事項を入力し、ページ下部のライセンスに合意のうえ申請を行ないます。

## 承認メールを確認する
Meta社から許可が降りると、登録したメールアドレス宛へメールが届きます。

![スクリーンショット 2024-09-25 13.38.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/846404/73521f86-b431-e100-f521-848a42f08a83.png)

## Hugging Faceのアカウント作成
HuggingFaceのアカウントを作成します。
先ほどのMeta社への利用申請に使用したメールアドレスと同じメールアドレスでアカウントを作成します。

https://huggingface.co/join

# Hugging Face上の操作完了まで
## Hugging Face上でのTokenの発行

アカウント作成完了後ログインし、Tokenを発行します。
なおTokenは個人情報のようなもので、他者へ共有してはいけません。

1. こちらにアクセス：https://huggingface.co/
1. 画面左側の「settings」をクリック
1. 画面左側の「Access Tokens」をクリック
1. 画面中央の「New Token」をクリック
1. 必要な欄を入力して「Generete a token」をクリック
    1. よくわからなければ、ひとまず、「Nameはお好きな名称(first_testとか)、Roleはread」でOKです

ここまで操作できると、画面上にTokenが発行されます。
このTokenは後で使うので、どこかに控えておきましょう。

## Hugging Face上でLlama3の申請を行う
申請が降りるまで数日かかることがあるようです。
申請は以下のページから可能です。

https://huggingface.co/meta-llama/Meta-Llama-3-8B

# Google colabで動かしてみる
以下で実際の実装例を公開しています。

https://colab.research.google.com/drive/1Ow9bgUURN3dEfmBDWVFFjd5y5ldKStOq#scrollTo=T8oqz6rEixy3

## ライブラリのimportとか、モデルのダウンロード
```python
# HuggingFaceにログイン
from huggingface_hub import notebook_login

notebook_login() # 上で取得したTokenを入力します
```

```python
# 量子化に必要なパッケージです
!pip install bitsandbytes

# Load model directly
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig

tokenizer = AutoTokenizer.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct")
```

```python
#　メモリが足りない場合は, 量子化のために以下を有効にしてください
bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.float16,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_use_double_quant=False,
)

model = AutoModelForCausalLM.from_pretrained(
            "meta-llama/Meta-Llama-3-8B-Instruct",
            device_map="auto",
            quantization_config=bnb_config,
            torch_dtype=torch.bfloat16,
        )
```

## 一般的なことを聞いてみる
```python
prompt = "Hugging Faceについて簡潔に説明して"

# プロンプトを直接トークン化する
input_ids = tokenizer(prompt, return_tensors="pt").input_ids.to(model.device)

# テキスト生成
outputs = model.generate(
    input_ids,
    max_new_tokens=128,
    eos_token_id=tokenizer.eos_token_id,
    do_sample=True,
)

# 生成結果のデコード
response = tokenizer.decode(outputs[0], skip_special_tokens=True)

print("\n---生成結果---\n", response)
```

>---生成結果---
 Hugging Faceについて簡潔に説明しておく。
Hugging Faceは、自然言語処理(NLP)のためのオープンソースフレームワークです。彼らは、 transformer という名前のarchitectureを基盤にした、多くのpre-trained language modelsを提供しています。これらのモデルは、様々なNLPタスクに対してfine-tuningすることができます。
Hugging Faceの主な特徴として、以下のようなものがあります。
1.**Transformer architecture**: Hugging Faceは、transformer architectureを基盤にしたpre-trained language modelsを提供しています。これらのモデルは、様々なNLP

## 個人的なことを聞いてみる
生成AIの弱点の１つに、「知らないことを聞かれた時に誤った回答をしてしまう」という点があります。

```pyhton
prompt = """
以下の質問に日本語で回答してください:
質問:Ryoは、2022年にどのようなを勉強をしていましたか？
回答:"""

# プロンプトを直接トークン化する
input_ids = tokenizer(prompt, return_tensors="pt").input_ids.to(model.device)

# テキスト生成
outputs = model.generate(
    input_ids,
    max_new_tokens=128,
    eos_token_id=tokenizer.eos_token_id,
    do_sample=True,
)

# 生成結果のデコード
response = tokenizer.decode(outputs[0], skip_special_tokens=True)

print("\n---生成結果---\n", response)
```

> 以下の質問に日本語で回答してください:
質問:Ryoは、2022年にどのようなを勉強をしていましたか？
回答:Ryoは、2022年にPythonプログラミング言語を勉強していました。

## RAGっぽいことをして、正解を答えてもらえるようにする
RAG（Retrieval-Augmented Generation）とは、生成AIが内部知識に頼るだけでなく、外部の情報を動的に取得して、より精度の高い応答やコンテンツを生成する手法です。

```python
query = "Ryoは、2022年にどのようなを勉強をしていましたか？"
retrieved_text = """
さて僕(Ryo)がKaggleを知ったのは、約4年前に地方公務員からベンチャー企業へ転職したときです。
「データサイエンスかっこいい、なりたい！」と思い（今思えば）特に勉強もしていない状態で、現職のデータサイエンス部の方にカジュアル面談をしていただきました。そこで「kaggleやりなよ」と言われたのが出会いです。けれど、「データサイエンス」や「プログラミング」とは縁遠い出自で、kaggleを始める基礎もないような状態でした。

学習パートとしては大きく3部構成です。
1. とにかくやってみる期（2020.1~2021.3）
2. 修士（経済学）への進学期（2021.4~2024.3）
3. "データサイエンス"頑張る期（2023.11~2024.4）
"""

# プロンプトを形成
prompt = f"""{retrieved_text}
上記の文章に基づいて、質問に日本語で回答してください。
質問: {query}
回答:"""

# トークン化
input_ids = tokenizer(prompt, return_tensors="pt").input_ids.to(model.device)

# テキスト生成
outputs = model.generate(
    input_ids,
    max_new_tokens=128,
    eos_token_id=tokenizer.eos_token_id,
    do_sample=True,
)

# 生成結果のデコード
response = tokenizer.decode(outputs[0], skip_special_tokens=True)

print("\n-----生成結果-----\n", response)
```

> 上記の文章に基づいて、質問に日本語で回答してください。
質問: Ryoは、2022年にどのようなを勉強をしていましたか？
回答: Ryoは、2022年の大半を、修士（経済学）への進学期に費やしました。つまり、2021.4~2024.3の間には、学習の焦点が経済学の領域にありました。


今回は、お試しということで、外部情報を直接代入します（そのため実際にはプロンプトエンジニアリングを行っています）。

なお文章は筆者のnoteから引用しています。よろしければこちらもご覧ください。

https://note.com/gr39my/n/nfdd6d0c4d85d

# 終わりに
今回は、Hugging FaceとMeta社のLlama3モデルを活用して、生成AIを動かしてみる手順を紹介しました。

プロンプトエンジニアリングを通じてAIに外部情報を提供し、精度の高い応答を生成する方法や、RAGに似たアプローチで外部情報を活用する流れも体験できたと思います。

これからも、生成AIの活用法は進化し続けるので、ぜひ色々なケースで試してみてください！