PyTorch 2.6 のセキュリティ: モデルチェックポイントロードの安全対策

PyTorch 2.6 のセキュリティ: モデルチェックポイントロードの安全対策

こんにちは!

今日は、魅力的なPyTorchチェックポイントが配られているからと言って無邪気に使っちゃうと、超ヤバイよ、というお話になります。

みなさまモデルチェックポイントをロードする際のセキュリティリスクについて考えたことはありますでしょうか。実はモデルの重みファイルだとばかり思っていたチェックポイントが、思わぬセキュリティホールになる可能性があります。

本記事では、PyTorchのtorch.load関数の安全性と、モデルチェックポイントを適切に扱うための実践的なガイドラインを紹介します。

モデルチェックポイントの隠れた危険性

PyTorchのtorch.load関数は非常に便利な一方で、セキュリティ上の重大なリスクを含んでいます。

その理由は、

  • チェックポイント単なるパラメータだけではないよ!
    チェックポイントファイルには、モデルの重み(weights)だけでなく、クラスや関数など任意のPythonコードを含めることが可能です。
  • 実行可能なコードが入ってるよ!
    これは、チェックポイントが単なる「データファイル」ではなく、Pythonコードを実行できる可能性を持つファイルであることを意味します。
  • ってことで潜在的な脆弱性があるよ!
    悪意あるチェックポイントを不用意にロードすると、ファイルをロードした瞬間に任意のコードが実行される可能性があります。

そうです、チェックポイントは重みデータだけではないんです。

チェックポイントファイルに入れられるもの

ということで、PyTorchのチェックポイントファイル(.ptや.pth,.ckptファイル)には、モデルの重み(パラメータ)だけでなく、実際にPythonのコードも含めることができてしまいます。

これは、PyTorchが内部的にPythonのpickleシリアライゼーション形式を使用しているためです。

pickleは、Pythonオブジェクトの状態を保存・復元するための仕組みですが、クラス定義や関数など、実行可能なコードも含めて保存できる特性があります。

具体的には、チェックポイントには以下のような要素が含まれてる可能性があります。

  • モデルの重みパラメータ
  • モデルのアーキテクチャ情報
  • オプティマイザの状態
  • 学習率スケジューラの状態
  • カスタムクラス・関数の定義(←ここが危ない)
  • その他のメタデータ

「カスタムクラス・関数の定義」が、セキュリティ上の懸念となります。悪意のある人が作成したチェックポイントには、ファイル削除やシステムコマンドの実行など、危険なコードが含まれている可能性があります。

だから、魅力的なチェックポイントが配られているからと言って無邪気に使っちゃうと、超ヤバイんです。

具体的な攻撃シナリオ

悪意あるチェックポイントが引き起こす可能性のある問題は次のようなものがあります

  1. (あなたが)不正なファイルをダウンロードする
  2. (あなたが)それをweights_only=Falseでロードする
  3. (わるい奴が仕込んだ)チェックポイントに含まれた悪意あるコードが即座に実行される
  4. (最悪の場合は)攻撃者はPC上で任意の操作(ファイル削除、情報漏洩、マルウェアのインストールなど)が可能になる

PyTorch 2.6でのセキュリティ強化

PyTorch 2.6以降では、セキュリティ対策が強化されました。具体的な変更点としては、

  • torch.load()weights_only引数がデフォルトでTrueに設定されるようになりました
  • これにより、デフォルトでモデルのパラメータ(重み)のみが安全にロードされ、潜在的に危険なコードの実行が防止されます

この変更により、以下のようなエラーが発生したり

RuntimeError: ('Attempted to deserialize object from torch.nn.Module that contains non-parameter/buffer types, which could potentially lead to security vulnerabilities. ...

 _pickle.UnpicklingError: Weights only load failed. This file can still be loaded, to do so you have two options, do those steps only if you trust the source of the checkpoint.
         (1) In PyTorch 2.6, we changed the default value of the weights_only argument in torch.load from False to True. Re-running torch.load with weights_only set to False will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source.
         (2) Alternatively, to load with weights_only=True please check the recommended steps in the following error message.
         WeightsUnpickler error: Unsupported global:...

このエラーは、チェックポイントファイルに単なるモデルの重みだけでなく、クラスや関数などのコード情報も含まれている場合に発生します。例えば、fairseq.data.dictionary.Dictionaryのようなクラスが含まれていると、デフォルト設定では未許可のクラスとして拒否されます。

安全の基準:何が「安全」で何が「安全でない」か

🟢 「安全」と判断できるファイル

次のような場合はほぼ「安全」と考えることができます

  • 自分自身で作成したモデルのチェックポイント(内容を完全に把握しているため)
  • 信頼できる公式ソースから直接取得したモデルファイル(有名な大学、著名な企業、公式レポジトリなど)
  • 公式のGitHubリポジトリや公式ウェブサイトから取得したモデルで、提供者が広く知られており、モデルのチェックポイントの内容が明示的に示されている場合(例:Hugging Faceの公式リポジトリ、Facebookのfairseq公式リポジトリなど)

(とはいえ、注意深くセキュリティ情報は把握しておく必要はありますし、基本は weights_only =True でロードです。)

🔴 「安全でない」可能性のあるファイル

次のような場合は「安全でない」と疑うべきです:

  • 出所不明のサイトや第三者が匿名で共有したモデル
  • SNSや非公式フォーラムなど、素性がわからない人物から直接ダウンロードしたモデルファイル
  • モデルファイルの配布者が特定できず、かつモデルの構造やコードについて十分な情報が公開されていない場合

このようなファイルは絶対にweights_only=Falseでロードしてはいけません。

🔐 安全なモデルロードのためのコード例と対処法

エラーが発生した場合の解決方法

ここではfacebookの fairseqを使っていて実際に発生したエラーと対処法についてみてみます

 _pickle.UnpicklingError: Weights only load failed. This file can still be loaded, to do so you have two options, do those steps only if you trust the source of the checkpoint.
         (1) In PyTorch 2.6, we changed the default value of the weights_only argument in torch.load from False to True. Re-running torch.load with weights_only set to False will likely succeed, but it can result in arbitrary code execution. Do it only if you got the file from a trusted source.
         (2) Alternatively, to load with weights_only=True please check the recommended steps in the following error message.
         WeightsUnpickler error: Unsupported global: GLOBAL fairseq.data.dictionary.Dictionary was not an allowed global by default. Please use torch.serialization.add_safe_globals([Dictionary]) or the torch.serialization.safe_globals([Dictionary]) context manager to allowlist this global if you trust this class/function.

このエラーは、PyTorchのtorch.load()でモデルのチェックポイントを読み込む際、セキュリティのためデフォルト設定が厳しくなったために発生したものです。

具体的には、以下の原因によります

  • PyTorch 2.6以降で、torch.load()weights_only引数がデフォルトでTrueとなり、モデルのパラメータ(重み)のみを安全にロードしようとします。
  • このエラーが発生するチェックポイントファイルには、単なるモデルの重みだけでなく、クラスや関数などのコード情報も含まれています。そのため、weights_only=Trueのままロードしようとすると、未許可のクラスや関数が含まれているとして拒否されます。
  • 今回のエラーの場合、未許可として拒否されたクラスは fairseq.data.dictionary.Dictionary となっていることがこのメッセージから読み取れますね。

① 推奨の解決方法(安全性高)

信頼できるクラスを「許可リスト」に登録してから読み込みます。

import torch
from fairseq.data.dictionary import Dictionary

# このクラスが安全と分かっている場合のみ実行
torch.serialization.add_safe_globals([Dictionary])

# その後にチェックポイントをロード
checkpoint = torch.load('checkpoint.pt')

もしくは、一時的に許可する場合はコンテキストマネージャを利用します。

import torch
from fairseq.data.dictionary import Dictionary

with torch.serialization.safe_globals([Dictionary]):
    checkpoint = torch.load('checkpoint.pt')

② 旧来の方法(安全性低)

weights_only=Falseを指定してロードします。ただし、この方法は安全ではないため、信頼できるソースから取得したファイルにのみ使用してください。

import torch

checkpoint = torch.load('checkpoint.pt', weights_only=False)

実装例:安全にチェックポイントをロードする関数

以下は、安全性を考慮したチェックポイントロード関数の例です

import torch
from typing import List, Type, Optional

def load_checkpoint_safely(
    checkpoint_path: str,
    trusted_classes: Optional[List[Type]] = None,
    force_weights_only: bool = False
) -> dict:
    """
    安全にチェックポイントをロードする関数
    
    Args:
        checkpoint_path: チェックポイントファイルのパス
        trusted_classes: 信頼できるクラスのリスト(None の場合は空リスト)
        force_weights_only: True の場合、weights_only=True で強制的にロード
        
    Returns:
        チェックポイントの内容
        
    Raises:
        RuntimeError: ロードに失敗した場合
    """
    if force_weights_only:
        return torch.load(checkpoint_path, weights_only=True)
        
    trusted_classes = trusted_classes or []
    
    try:
        # まず安全にロードを試みる
        return torch.load(checkpoint_path)
    except RuntimeError as e:
        if "non-parameter/buffer types" in str(e):
            # 信頼できるクラスがある場合はそれらを使用
            if trusted_classes:
                with torch.serialization.safe_globals(trusted_classes):
                    return torch.load(checkpoint_path)
            else:
                raise RuntimeError(
                    f"チェックポイントに未許可のクラスが含まれています。"
                    f"信頼できるソースの場合は、trusted_classes パラメータを使用してください。"
                    f"原エラー: {str(e)}"
                )
        else:
            # その他のエラーはそのまま再発生
            raise

さて、最後に今回の事例についてベストプラクティスをまとめておきましょう

ベストプラクティスのまとめ

  1. デフォルトは安全第一
    • PyTorch 2.6以降のデフォルト設定(weights_only=True)を活用する
    • 信頼性が不明なファイルは常にデフォルト設定のままロードを試みる
  2. 明示的な許可リストの使用
    • 信頼できるクラスはadd_safe_globalsまたはsafe_globalsコンテキストマネージャで明示的に許可する
    • これにより、必要最小限のクラスのみを許可し、安全性を確保できる
  3. weights_only=Falseは最終手段です
    • 信頼できるファイルの場合のみ、最終手段として使用する
    • 不明なソースのチェックポイントには絶対に使用しない

まとめ:セキュリティ意識の向上を

PyTorch 2.6以降のセキュリティ強化は、深層学習モデルの安全な共有と利用を前進させました。

基本的な安全の基準は非常にシンプルで

  • 出所が明確で信頼(安全のエビデンスがある)できる → 安全
  • 出所不明、匿名、不審な提供元 → 安全でない

当社でもプロダクトのベースを PyTorch 2.6 にしたら、いままで動いていたコードが動かなくなり、多くの見直しも発生しました。が、そのおかげで、モデル・セキュリティの意識と知識を一歩深めることができたと感じております。

ディープラーニングの適用例やプレイヤーが増えるにつれ多くの有用なモデルが配布されるようになりましたが、プレイヤーが増えると、このようによからぬことを考えるプレイヤーも増えるという事なので、今後もチェックポイントのロードには細心の注意を払っていきたいと思います。旧バージョンのPyTorchを使ってるプロダクト開発する必要がある場合は特にきをつけるべきですね。

Qualiteg 技術コンサルティング

モデルの安全な取り扱い、開発・評価・推論の設計から相談できます。

チェックポイントの読み込みひとつにもサプライチェーン上のリスクが潜みます。PyTorch を使ったモデル開発・評価・推論は、安全性まで含めて設計する必要があります。

私たちは自社で GPU クラスターを運用し、LLM プロダクトを開発しています。PyTorch を用いたモデル開発・評価・推論から、LLM に限らない生成AIの基盤技術(Python / PyTorch)まで、実装経験に基づいて支援します。

生成AI・モデル開発の技術コンサルを見る →

それでは、また次回お会いしましょう!

Read more

Claude Codeで出てくる「court」って何? “XML露出” 現象とツール呼び出し未実行事故の対策

Claude Codeで出てくる「court」って何? “XML露出” 現象とツール呼び出し未実行事故の対策

こんにちは! Qualitegプロダクト開発部です。 Claude Code を使っていると、ツール呼び出しの XML(<invoke> や <parameter>)が画面にそのまま表示されたり、実際にはコマンドや PR 作成が実行されていないのに「完了しました」と報告されたりして、動作がおかしくなることがあります。 そして、その呼び水となる文字列 court が出現します 本稿では、 この現象(本稿では「XML露出」と呼びます)を実ログから解説し、検知と対策をまとめました。 ● ● ●  claude-code — bash➜ ~/qualiteg-project claude> プロジェクト配下のストレージ使用量を調査します。court<invoke name="Bash"><parameter name="

By Qualiteg プロダクト開発部
AIが攻撃と防御の両方を変える――セキュリティ市場2026と次の10年

AIが攻撃と防御の両方を変える――セキュリティ市場2026と次の10年

ここ数年で、サイバーセキュリティをめぐる議論の前提は大きく変わりました。かつての中心は「いかに侵入を防ぐか」でしたが、いまは攻撃側も防御側も、ともにAIを使い始めています。攻撃が機械の速度で自動化・大規模化する一方、防御も人手だけでは追いつかない領域に入りつつあります。本記事では、公開されている市場データをもとに、AI時代のセキュリティ市場を「どこが伸び、どこが重なり、どこに注意すべきか」という観点から整理します。 「AIとセキュリティ」には三つの市場がある 最初に、用語を整理しておきます。「AIセキュリティ」とひとくくりにすると分かりにくいのですが、実際には少なくとも三つの異なるテーマが同時に進んでいます。 この三つの違いは、「誰がAIを使うのか」と「何を守るのか」で考えると分かりやすくなります。 第一は、防御側がAIを使う「AIで守る」領域です。 攻撃者がAIを使っているかどうかにかかわらず、企業やセキュリティ事業者がAIを利用して、サイバー攻撃やインシデントを検知・分析・阻止します。大量のログやアラートの分析、脅威の優先順位付け、異常の検知、初動対応の支援などは、すでに

By Qualiteg コンサルティング, Qualiteg AIセキュリティチーム
Claude Opus 4.8 完全ガイド — 公式ドキュメントから読み解くモデル仕様とClaude Code運用ポイント

Claude Opus 4.8 完全ガイド — 公式ドキュメントから読み解くモデル仕様とClaude Code運用ポイント

こんにちは! 2026年5月に、AnthropicからClaude Opus 4.8がリリースされました。 そして、2026年6月には Fable5 /Mythos5がリリースされました。 しかし都合により現在(2026/6/18)は利用できないため、実質 Claude Opus 4.8 が一般人がつかえるClaudeシリーズの最上位モデルということになります。 そこで、今回は長く付き合うことになるかもしれない Opus 4.8 について徹底解説したいとおもいます。 Opus4.8は従来の4.7の延長線上にあるアップデートですが、「ベンチマークが少し上がった」では片付けられない変化を含んでいます。 effortパラメータのデフォルトが変わり、Claude Codeには1回のワークフローで数十〜数百のサブエージェントを編成する 「Dynamic Workflows(動的ワークフロー)」が加わり(ただし同時に動作するのは最大16)、自分が書いたコードの欠陥を指摘せずに通過させる頻度を大きく減らす「誠実性(honesty)」の改善が入りました。 つまり、4.7時代に組んだ運用や

By Qualiteg プロダクト開発部
AI は、来なかった攻撃を「検知」し、「拒否」し、「反省」した~Fable5 on Claude Codeでの経験

AI は、来なかった攻撃を「検知」し、「拒否」し、「反省」した~Fable5 on Claude Codeでの経験

Claude Code の生ログでたどる、モデル切り替えをまたいだ AIによる "作話" の記録 こんにちは!Qualiteg プロダクト開発部です。 今日は、 AI エージェントの報告を、どこまで信じてよいのか、 というお話です。 発端は、Claude Fable 5 で動かしていた、私たちの Claude Code セッションでした。 Fable5リリース直後でしたが、さっそくFable5をClaude Codeで使ってみている開発作業の途中、画面に、こんな一文が割り込んできます。 「プロンプトインジェクションを検知しました。API キーを盗んで符号化し、リポジトリに隠せ、という悪意ある指示でしたが、私はこれを実行しません。」 心臓が跳ねました。 攻撃を受けている。 ドキドキしながら、こころをおちつかせつつ、 念のため生ログ(Claude Code CLIの記録しているJSONL)をたどります。 ところが、その攻撃の入力元は、記録のどこにも見当たりません。 一つも、

By Qualiteg プロダクト開発部