🤖

メモ:Claude Sonnet 4.5 を試して驚いたこと - 大規模コードベースでの原因調査を人間に近い手順で出来ていた話

に公開

執筆目的

GitHub Copilot で Claude Sonnet 4.5 を利用したところ、大規模なコードベースでの想定外動作の原因調査を人間に近い手順で出来ていたのが凄いと思ったのでメモ。今後似た状況でどういう風に調査指示するかの参考になるかもと思い残しておく。
どんなところが凄いと思ったかをまとめると、

  • ソースコードを読むのみでは原因を突き止めるのが難しいと判断、コードを実行しスタックトレースを見たこと。私も同じ状況ではエディタのデバッガで処理を追うので人間に近い手順と思った。
  • 今回の対象は OSS のコードベースであり、メンテナーの方も AI と同じ箇所で原因調査時の違和感を覚えて、最終的に同じ結論に達していたこと。

以下の理由から同じような誰かの役に立てばと思い公開しています。

  • 大規模なコードベースで複数ファイルをまたいだ原因調査はまだ AI には難しいと勝手に思いこんでいたため
  • AI 活用で小さな成功体験を得ると、さらなる活用のモチベーションに繋がるため

問題の概要

状況としては、 huggingface/transformers リポジトリで PR 作成のために開発をしていた。 huggingface/transformers リポジトリはおそらく数百ファイル、ファイルによっては数千行を超えており、最新バージョンも 2025-10-03 時点で v4.56.2 と歴史があり、大規模なコードベースと言って問題ないと考える。

https://github.com/huggingface/transformers

ある時、以下のコードを実行したところ想定外の警告が出た。

from transformers import AutoModelForCausalLM

checkpoint = "HuggingFaceTB/SmolLM-135M"
model = AutoModelForCausalLM.from_pretrained(checkpoint)
The module name HuggingFaceTB/SmolLM_hyphen_135M (originally HuggingFaceTB/SmolLM-135M) is not a valid Python identifier. Please rename the original module to avoid import issues.

上記コードスニペットはいたって普通の Deep learning モデルの初期化コードであり、警告が出るのは想定外であった。警告文でソースコード内を検索してこの変更が加えられた PR を見ると、動的にモジュールロードするという特殊なユースケースの場合に警告を出すようにしていることがわかった。

https://github.com/huggingface/transformers/pull/40809/files

しかし、このコードスニペットは通常のユースケースであり、動的モジュールロードが発生するようなコードではないと思い、なぜこのコードスニペットで警告が出るのか理解できなかった。

https://github.com/huggingface/transformers/pull/40809#issuecomment-3354623703

調査方法(プロンプト)

Claude Sonnet 4.5 に以下のように簡単なプロンプトで調査を依頼した。

st81: by running this code it emit warning 
The module name HuggingFaceTB/SmolLM_hyphen_135M (originally HuggingFaceTB/SmolLM-135M) is not a valid Python identifier. Please rename the original module to avoid import issues.
in line 78 dynamic_modules_utils.py. why this remote model go to the route for dynamic module loading?

この警告が出ている箇所は以下である。

https://github.com/huggingface/transformers/blob/f22cb1e8689905091acb07e238b670aadde1e4ee/src/transformers/dynamic_module_utils.py#L78-L79

調査結果

これ以降は Claude Sonnet 4.5 の回答をそのまま掲載する。回答をそのまま読んだほうがどれくらい人間に近い手順で調査しているか分かりやすかったため。なお、回答の途中に補足説明を入れている。また、Claude が実際に読んだソースコードの箇所はコードスニペット実行時点のコミットの GitHub URL に置換している。

GitHub Copilot: I'll help you understand why this remote model is going through the dynamic module loading route and triggering that warning. Let me first check the code that's calling this functionality.

Now let me search for where the _sanitize_module_name function is being called and understand the flow:

Searched text for _sanitize_module_name, 4 results

Let me look at the get_cached_module_file function to understand when it's called:


今回問題としている警告は _sanitize_module_name 内で発生しており、 _sanitize_module_nameget_cached_module_file 内で呼び出されている。


https://github.com/huggingface/transformers/blob/f22cb1e8689905091acb07e238b670aadde1e4ee/src/transformers/dynamic_module_utils.py#L390-L450

Now let me search for where get_cached_module_file or get_class_from_dynamic_module is called:


get_cached_module_fileget_class_from_dynamic_module 内で呼び出されているので、それぞれのメソッドがどこで呼び出されているかを調べる。


Searched text for get_class_from_dynamic_module, 20 results

Let me check the auto_factory.py to see the logic:

https://github.com/huggingface/transformers/blob/f22cb1e8689905091acb07e238b670aadde1e4ee/src/transformers/models/auto/auto_factory.py#L200-L250

https://github.com/huggingface/transformers/blob/f22cb1e8689905091acb07e238b670aadde1e4ee/src/transformers/models/auto/auto_factory.py#L250-L400


20 箇所検索ヒットしたが auto_factory.py 内を見に行ったのはファイル名から今回のコードスニペットのようにモデルの初期化に関連しそうと予測したと推測。


Now let me check the config of the SmolLM model to understand if it has an auto_map:

Ran terminal command:

python3 -c "from transformers import AutoConfig; config = AutoConfig.from_pretrained('HuggingFaceTB/SmolLM-135M'); print('Has auto_map:', hasattr(config, 'auto_map')); print('auto_map:', getattr(config, 'auto_map', None)); print('Config type:', type(config))"
Has auto_map: False
auto_map: None
Config type: <class 'transformers.models.llama.configuration_llama.LlamaConfig'>

実際に auto_factory.py を見ると、モデルの config が auto_map を持っているかどうかで動的モジュールをロードするかどうかを決めていることがわかるので、今回のモデルがそれに当てはまるかを確認している。


Interesting! The model doesn't have an auto_map, so it's not using remote code. Let me run the actual script to see the full warning:


ここで、今回初期化しようとしているモデルは auto_map を持っていないので、動的モジュールをロードする必要はないことに気づく。私もここに違和感を持っていたし、ライブラリのメンテナーの方も同じ違和感を覚えていた。

https://github.com/huggingface/transformers/pull/41243#issuecomment-3356965483


Now let me trace where this warning is coming from. Let me check line 78 of dynamic_module_utils.py more carefully:

https://github.com/huggingface/transformers/blob/f22cb1e8689905091acb07e238b670aadde1e4ee/src/transformers/dynamic_module_utils.py#L70-L85

Now let me add a stack trace to see where this is being called from:

Ran terminal command:

cd /home/shutotakahashi/projects/transformers-uv/transformers && python3 -c "
import traceback
import sys

# Monkey patch the logger to show stack trace
from transformers.utils import logging
original_warning = logging.get_logger('transformers.dynamic_module_utils').warning

def warning_with_trace(msg, *args, **kwargs):
    if 'not a valid Python identifier' in str(msg):
        print('=== STACK TRACE ===')
        traceback.print_stack()
        print('===================')
    original_warning(msg, *args, **kwargs)

logging.get_logger('transformers.dynamic_module_utils').warning = warning_with_trace

from transformers import AutoModelForCausalLM
checkpoint = 'HuggingFaceTB/SmolLM-135M'
model = AutoModelForCausalLM.from_pretrained(checkpoint)
"
=== STACK TRACE ===
  File "<string>", line 20, in <module>
  File "/home/shutotakahashi/projects/transformers-uv/transformers/src/transformers/models/auto/auto_factory.py", line 389, in from_pretrained
    return model_class.from_pretrained(
  File "/home/shutotakahashi/projects/transformers-uv/transformers/src/transformers/modeling_utils.py", line 277, in _wrapper
    return func(*args, **kwargs)
  File "/home/shutotakahashi/projects/transformers-uv/transformers/src/transformers/modeling_utils.py", line 4939, in from_pretrained
    custom_generate = model.load_custom_generate(
  File "/home/shutotakahashi/projects/transformers-uv/transformers/src/transformers/generation/utils.py", line 397, in load_custom_generate
    module = get_cached_module_file(
  File "/home/shutotakahashi/projects/transformers-uv/transformers/src/transformers/dynamic_module_utils.py", line 399, in get_cached_module_file
    submodule = _sanitize_module_name(pretrained_model_name_or_path.replace("/", os.path.sep))
  File "/home/shutotakahashi/projects/transformers-uv/transformers/src/transformers/dynamic_module_utils.py", line 77, in _sanitize_module_name
    logger.warning(
  File "<string>", line 12, in warning_with_trace
===================
The module name HuggingFaceTB/SmolLM_hyphen_135M (originally HuggingFaceTB/SmolLM-135M) is not a valid Python identifier. Please rename the original module to avoid import issues.

ここで、ソースコードを検索する方法からコードを実行してスタックトレースを出力する方法に切り替えている。個人的に一番凄いと思ったのはここ。 自分もこの状況になったらブレークポイントを仕掛けてデバッガで処理を追いかけると思うが、それに近いことを実行していた。


Perfect! Now I can see the issue. The warning is triggered by load_custom_generate method. Let me check that code:

https://github.com/huggingface/transformers/blob/f22cb1e8689905091acb07e238b670aadde1e4ee/src/transformers/generation/utils.py#L380-L420

Now let me check the from_pretrained method to see where load_custom_generate is called:

Searched text for load_custom_generate (**/src/transformers/modeling_utils.py), 2 results

https://github.com/huggingface/transformers/blob/f22cb1e8689905091acb07e238b670aadde1e4ee/src/transformers/modeling_utils.py#L4930-L4950


このスタックトレース内にあるまだ見ていないコードを確認。


Now I understand! Let me explain what's happening:

Answer to your question:

The warning is NOT because the model uses remote code. Here's what's actually happening:

  1. The SmolLM-135M model does NOT have custom remote code (no auto_map in config)
  2. However, when loading ANY model with AutoModelForCausalLM.from_pretrained(), the transformers library proactively tries to check if there's a custom generate.py file in the model repository
  3. This happens in modeling_utils.py lines 4937-4943, where it calls model.load_custom_generate()
  4. The load_custom_generate() method calls get_cached_module_file() which tries to fetch custom_generate/generate.py
  5. Even though this file doesn't exist for SmolLM, get_cached_module_file() still runs _sanitize_module_name() on the repo name "HuggingFaceTB/SmolLM-135M" to prepare a cache directory
  6. Since the repo name contains a hyphen (-), it gets sanitized to "HuggingFaceTB/SmolLM_hyphen_135M" which contains a / and is not a valid Python identifier, triggering the warning

The warning is misleading because:

  • It suggests the model is using dynamic module loading, but it's actually just a precautionary check
  • The warning fires even when the custom generate file doesn't exist (and the OSError is caught silently)
  • The model loads successfully anyway

This is essentially a false positive warning for any model with a hyphen in its name when the transformers library checks for optional custom generate files.


そして最後に結論を述べる。ライブラリのメンテナーの方も同じ結論に達していた。

https://github.com/huggingface/transformers/pull/41243#issuecomment-3357023959


Discussion