Hugging FaceとLangChainでオープンLLMモデルを無料で試す方法!

ChatGPTは非常に便利ですが、APIを使って色々なことをしようと思うとどうしてもコストが気になります。そこで今回は、オープンソースで開発されているLLMをうまく使って、似たようなことができないか模索しました。

様々なモデルが登録されているHuggingFaceとオープンAIなどのモデルを実行するのに便利なLangChainを組み合わせて、サクッと試してみました。

Hugging Faceとは?

Hugging Faceは、様々な機械学習のライブラリを開発している企業で、モデルやデータセットの共有を促進するプラットフォームも提供しています。 Hugging Faceは、自然言語処理NLP)のタスクにおいて特に有名でしたが、最近は画像系など様々なタスクに利用できるモデルがあります。

Hugging Faceは、モデルのトレーニングやファインチューニングに加えて、モデルやデータセットの公開・共有を可能にするプラットフォームを提供しており、この中に今回利用するAPIもあります。CPUのみなので、あまり大きなモデルを使えないのですが、無料で利用可能です。

Hugging Face APIとは?

Hugging Face APIは、開発者に対してモデルの利用や推論を簡単に行う手段を提供します。

Hugging Face APIを利用するためには、まずAPIトークンを取得する必要があります。APIトークンは、Hugging Faceの公式ウェブサイトでアカウントを作成し、APIの使用に対する認証情報を取得することで入手できます。

登録は以下でできます。 https://huggingface.co/join トークンは以下のURLでNewTokenをクリックすると生成されます。 https://huggingface.co/settings/tokens

トークンを取得したら、環境変数としてHUGGINGFACEHUB_API_TOKENトークンを設定しておく必要があります。

セキュリティ上の理由からトークンを直接コードに記入しない方がいいため、今回は、.envファイルや環境変数を使用してトークンを設定することが推奨されます。 まずは作業ディレクトリに移動して、.envファイルを作成します。 そしてこの環境変数を読み込むためには以下のようなコードを書きます

from dotenv import load_dotenv

# .envファイルの内容を読み込見込む TrueならOK

load_dotenv()

Hugging Face APIを利用する場合、LangChainではHuggingFaceHubクラスを使用します。以下のコード例をご覧ください。

Hugging Face APIを使ってLangChainでLLMモデルを利用する方法

Hugging Face APIを介してLangChainでLLMモデルを利用する方法を解説します。Hugging Face APIを使用することで、Hugging Face上に存在するさまざまなモデルを簡単に利用することができます。

以下のコードを使用してHugging Face APIを介してLLMのインスタンスを作成します。

GoogleColaboratory使う場合は以下のライブラリーをインストールします。

!pip install openai langchain python-dotenv transformers 
!pip list | grep langchain
from langchain import HuggingFaceHub


repo_id = "モデルのリポジトリID"  # Hugging Face上でモデルを特定するためのID
model_kwargs = {"パラメータ1": 値1, "パラメータ2": 値2}  # モデルのパラメータを指定する
llm = HuggingFaceHub(repo_id=repo_id, model_kwargs=model_kwargs)

上記のコードでは、repo_idにはHugging Face上のモデルのリポジトリIDを指定します。また、model_kwargsにはモデルごとに異なるパラメータを指定することができます。具体的なパラメータは各モデルのドキュメントを参照してください。

LLMのインスタンスを準備したら、LangChainを使用して質問やテキスト生成を行うことができます。以下がコードの書き方です。具体例はそのあとにあります。

from langchain import LLMChain, PromptTemplate


template = """Question: {question}


Answer: {answer}"""
prompt = PromptTemplate(template=template, input_variables=["question", "answer"])
llm_chain = LLMChain(prompt=prompt, llm=llm)


question = "質問の内容"
answer = llm_chain.run(question)


print(answer)

上記のコードでは、templateには質問と回答のテンプレートを指定し、input_variablesにはテンプレート内で使用する変数のリストを指定します。LLMChainクラスを使用してLLMとテンプレートを組み合わせ、質問に対して回答を取得します。

それでは実際にgpt2モデルを使って、自己紹介の続きを書いてもらうプロンプトを実行してみたいと思います。

from langchain import HuggingFaceHub, LLMChain, PromptTemplate


hub_llm = HuggingFaceHub(
    repo_id='gpt2',
    model_kwargs={'temperature': 0.7, 'max_length': 100}
)


prompt = PromptTemplate(
    input_variables=["name", "place"],
    template="Hello, my name is {name} and I'm from {place}. Nice to meet you!"
)


hub_chain = LLMChain(prompt=prompt, llm=hub_llm, verbose=True)


name1 = "Alice"
place1 = "New York"
response1 = hub_chain.run(name=name1, place=place1)
print(f"Response for {name1} from {place1}: {response1}\n")


name2 = "Bob"
place2 = "London"
response2 = hub_chain.run(name=name2, place=place2)
print(f"Response for {name2} from {place2}: {response2}\n")


name3 = "Charlie"
place3 = "Tokyo"
response3 = hub_chain.run(name=name3, place=place3)
print(f"Response for {name3} from {place3}: {response3}\n")

上記のコードでは、GPT-2のモデルをロードし、LLMChainを作成しています。プロンプトには「名前(name)」と「場所(place)」という入力変数を使用し、自己紹介文を生成します。

具体的な例として、AliceさんがNew York出身である場合、BobさんがLondon出身である場合、CharlieさんがTokyo出身である場合のそれぞれの回答を取得しています。

上記のコードを実行すると、各自の名前と場所に基づいた自己紹介文が生成されます。

(なお、verbose=Trueとしているため、処理の進捗状況や生成されたトークン数が表示されます。)

アウトプットは次のようになりました。

> Entering new  chain...
Prompt after formatting:
Hello, my name is Alice and I'm from New York. Nice to meet you!


> Finished chain.
Response for Alice from New York: 


Alice: Hello, my name is Alice and I'm from New York. Nice to meet you!


Alice: Hello, my name is Alice and I'm from New York. Nice to meet you!


Alice: Hello, my name is Alice and I'm from New York. Nice to meet you!


Alice: Hello, my name is Alice and I'm from New York


> Entering new  chain...
Prompt after formatting:
Hello, my name is Bob and I'm from London. Nice to meet you!


> Finished chain.
Response for Bob from London: 


I'm a freelance writer and I'm looking for a job. I'm looking for a freelance writer to write a short story for a magazine. I'm looking for a freelance writer to write a short story for a magazine. I'm looking for a freelance writer to write a short story for a magazine. I'm looking for a freelance writer to write a short story for a magazine. I'm looking for



> Entering new  chain...
Prompt after formatting:
Hello, my name is Charlie and I'm from Tokyo. Nice to meet you!


> Finished chain.
Response for Charlie from Tokyo: 


I'm a Japanese-American, and I'm a member of the Japanese American Association. I'm a member of the American Association for the Advancement of Science. I'm a member of the American Association for the Advancement of Science. I'm a member of the American Association for the Advancement of Science. I'm a member of the American Association for the Advancement of Science. I'm a

正直なところちょっと微妙なものが多いですね。 最初の例は全くうまくいっていませんが後ろの2つはまだある程度文章にはなっているかなという感じです。

あまり大規模なモデルはAPIに対応していないケースが多そうなので、なかなかCPUで動く高性能のモデルというのは難しそうだなという印象です。