はじめに
本記事は新納浩幸氏の著書「LLMのファインチューニングとRAG」(2024年5月オーム社より出版)をもとに、ズブの素人がPythonとOpenCLAMを使用して、LLMのファインチューニングとRAGをハンズオンで自己学習する過程での、詰まったポイントと回避策の記録です。
出版から1年経っていない書籍をもとにしていますが、バージョンやOSの違いによるものか、最初のステップで躓いて苦労しました。
著作権に関わる制限事項
本記事では「LLMのファインチューニングとRAG」内で記述されている文書およびコードに関し、一切複製・転記は致しません。
これは著作権法上及び、同書籍の下記リンク先「ダウンロード」の項に書かれている転載、複製の禁止を遵守するためですのでご容赦ください。
学習環境
項目 | 仕様 |
---|---|
OS | macOS Sequoia 15.2 |
CPU | Apple M3 |
Python | 3.12.0 |
使用ライブラリ
ライブラリ名 | バージョン |
---|---|
torch | 2.5.1 |
torchvision | 0.20.1 |
torchaudio | 2.5.1 |
transformers | 4.47.1 |
accelerate | 1.2.1 |
最初の躓きポイントでした。主軸として使用するライブラリ「torch」はPythonの最新バージョンで使用できない可能性があります。
PyTorchの公式リリース情報から、利用可能なPythonのバージョンを事前確認しておくことを推奨します。
筆者はバージョンを3.18.1→3.12.0にダウングレードしました。
ライブラリのインストール
pip3 install torch torchvision torchaudio
pip3 install transformers accelerate
試行錯誤の記録
OpenCLAM-smallへの問い合わせを書籍の通り実装して実行するとエラーが発生しました。
躓き1
ファイル階層
tree
.
└── Chapt1
└── llm-based-use.py
実行結果
Python3 ./Chapt1/llm-based-use.py
The `GPTNeoXSdpaAttention` class is deprecated in favor of simply modifying the `config._attn_implementation`attribute of the `GPTNeoXAttention` class! It will be removed in v4.48
Setting `pad_token_id` to `eos_token_id`:0 for open-end generation.
首都
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/transformers/modeling_utils.py", line 3897, in from_pretrained
).start()
^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/process.py", line 121, in start
self._popen = self._Popen(self)
^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/context.py", line 224, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/context.py", line 289, in _Popen
return Popen(process_obj)
^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/popen_spawn_posix.py", line 32, in __init__
super().__init__(process_obj)
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/popen_fork.py", line 19, in __init__
self._launch(process_obj)
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/popen_spawn_posix.py", line 42, in _launch
prep_data = spawn.get_preparation_data(process_obj._name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/spawn.py", line 164, in get_preparation_data
_check_not_importing_main()
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/spawn.py", line 140, in _check_not_importing_main
raise RuntimeError('''
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
To fix this issue, refer to the "Safe importing of main module"
section in https://docs.python.org/3/library/multiprocessing.html
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/spawn.py", line 122, in spawn_main
exitcode = _main(fd, parent_sentinel)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/spawn.py", line 131, in _main
prepare(preparation_data)
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/spawn.py", line 246, in prepare
_fixup_main_from_path(data['init_main_from_path'])
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/multiprocessing/spawn.py", line 297, in _fixup_main_from_path
main_content = runpy.run_path(main_path,
^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen runpy>", line 286, in run_path
File "<frozen runpy>", line 98, in _run_module_code
File "<frozen runpy>", line 88, in _run_code
File "/Users/yoda/LernLLMAndRAG/Chapt1/llm-based-use.py", line 4, in <module>
model = AutoModelForCausalLM.from_pretrained("cyberagent/open-calm-small")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/transformers/models/auto/auto_factory.py", line 564, in from_pretrained
return model_class.from_pretrained(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/transformers/modeling_utils.py", line 3941, in from_pretrained
raise EnvironmentError(
OSError: Can't load the model for 'cyberagent/open-calm-small'. If you were trying to load it from 'https://huggingface.co/models', make sure you don't have a local directory with the same name. Otherwise, make sure 'cyberagent/open-calm-small' is the correct path to a directory containing a file named pytorch_model.bin, tf_model.h5, model.ckpt or flax_model.msgpack.
結果こそ標準出力されるものの、大量にトレースバックが出力されました。トレースバックの内容があまりにも多すぎて、無視して進めるのも厳しいので、これが出力されないようにしたいところ。
躓き2
トレースバックの内容を消すために、mkdir -p cyberagent/open-calm-small
コマンドでディレクトリを用意。
ファイル階層は以下の通り。
tree
.
├── Chapt1
│ └── llm-based-use.py
└── cyberagent
└── open-calm-small
実行結果
Python3 ./Chapt1/llm-based-use.py
Traceback (most recent call last):
File "./Chapt1/llm-based-use.py", line 4, in <module>
model = AutoModelForCausalLM.from_pretrained("cyberagent/open-calm-small")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/transformers/models/auto/auto_factory.py", line 526, in from_pretrained
config, kwargs = AutoConfig.from_pretrained(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/transformers/models/auto/configuration_auto.py", line 1051, in from_pretrained
return CONFIG_MAPPING[pattern].from_dict(config_dict, **unused_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/transformers/configuration_utils.py", line 734, in from_dict
config = cls(**config_dict)
^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/transformers/models/rag/configuration_rag.py", line 128, in __init__
raise ValueError(
ValueError: A configuraton of type rag cannot be instantiated because both `question_encoder` and `generator` sub-configurations were not passed, only {'attn_implementation': None}
事態が悪化。結果も返さなくなりました。
躓き3
一旦前項で作ったディレクトリは削除します。
代わりに、LLMのモデルもローカルにダウンロードして格納するためのディレクトリ「LLM」を作成します。
rm -rf cyberagent/open-calm-small
mkdir LLM
ファイル階層
tree
.
├── Chapt1
│ └── llm-based-use.py
└── LLM
├── config.json
├── generation_config.json
├── pytorch_model.bin
├── special_tokens_map.json
├── tokenizer.json
└── tokenizer_config.json
LLMフォルダ内のファイルは以下から必要な6ファイルをダウンロードして格納しています。
モデルの指定箇所と、一部の内容をHugging Faceのサンプルに則り修正。
model = AutoModelForCausalLM.from_pretrained("./LLM", device_map="auto", torch_dtype=torch.float32)
tokenizer = AutoTokenizer.from_pretrained("./LLM")
input = tokenizer("東京は日本の", return_tensors="pt").to(model.device)
実行結果
Python3 ./Chapt1/llm-based-use.py
The `GPTNeoXSdpaAttention` class is deprecated in favor of simply modifying the `config._attn_implementation`attribute of the `GPTNeoXAttention` class! It will be removed in v4.48
Setting `pad_token_id` to `eos_token_id`:0 for open-end generation.
首都
トレースバックは出力されなくなりました。
出力結果も標準出力されるよう戻りましたが、警告メッセージは出たままです。
最初の警告は非推奨のメッセージで、ざっと見た感じではOpenCLAMが参照しているGPT-NeoXから出力されているように思えたので、手の出しようがなさげに思えます。
最終的にうまくいった構成
pad_token_id
に関する警告を出力させないように、generateメソッドにパラメータpad_token_id=tokenizer.eos_token_id
を追加しました。
実行結果
Python3 ./Chapt1/llm-based-use.py
The `GPTNeoXSdpaAttention` class is deprecated in favor of simply modifying the `config._attn_implementation`attribute of the `GPTNeoXAttention` class! It will be removed in v4.48
首都
終わりに
これでようやく冒頭に紹介した書籍の4ページ目以降に進められます。
前途多難な感じは否めませんが、MacにおいてOpenCLAM-SmallはLlama 3.2より高速で結果を返してくれているので、その点に関しては使用感が良いので、ストレスフリーでプログラミングできることを期待します。
そもそもですが、「LLMのファインチューニングとRAG」は対象読者を、PyTorchを使用してプログラムを作成した経験がある、初級者から中級者としています。
初心者がハンズオンとして参考にする書籍ではないので、まずは別の入門書などを入り口にすべきでした。
参考