本番運用におけるPyTorch+CUDAサーバーでの「Unknown Error」問題とその対策

本番運用におけるPyTorch+CUDAサーバーでの「Unknown Error」問題とその対策

こんにちは!Qualitegプロダクト開発部です。

今日は、GPUをつかった商用サービスにて悩ましい、テストは全部通るけど、長時間運用をしていると急に起こる「CUDA error: unknown error」についての内容です。

これ、出会うと残念な気持ちになりますが、けっこうGPU商用サービス界隈では「あるある」なんです。

原因を真面目に探るには CUDAバージョン、PyTorchバージョンの調合具合、実際のアプリケーションコードまですべてソースまで追う必要があるのですが、多くの場合、運用でカバーします。

なぜなら仮に1つ原因をみつけて対処できたとしても、CUDAバージョンはしょっちゅうあがりますし、PyTorchもそれに追従して頻繁に更新されます。さらにやっかいなことに、1日、2日、いや1週間くらいは安定的に動作しているようにみえて、数週間後にとつぜんエラーが出るといった具合なので、修正確認の難易度が高いんです。

そこで本日は「開発環境や実験環境」ではなく「本番環境」で発生しがちなこのCUDA Unknown Error について問題の原因と実践的な対策について解説します。

問題の具体例

典型的なエラーは次のようなスタックトレースとして現れます:

RuntimeError: CUDA error: unknown error
CUDA kernel errors might be asynchronously reported at some other API call, so the stacktrace below might be incorrect.
For debugging consider passing CUDA_LAUNCH_BLOCKING=1
Compile with `TORCH_USE_CUDA_DSA` to enable device-side assertions.

特に多く見られるのは、NumPy配列からPyTorchテンソルへの変換時に発生するエラーです:

img = torch.from_numpy(img.copy()).to(device, dtype=torch.float32)

なぜこの問題が発生するのか

この問題が発生する主な理由は以下のようなものがかんがえられます

1. CUDA・PyTorchのバージョン互換性の問題

CUDAとPyTorchのバージョンをアップグレードした後に、このようなエラーが突然発生するケースが多く見られます。

特にマイナーアップデートでさえ、内部実装の変更によって未知の互換性問題が引き起こされることがあります。例えば、CUDA 12.4から12.8へのアップグレード後、それに追従したPyTorchのアップグレード、また、そのために Pythonのバージョンをアップグレードしたときに付随して問題が発生することがよくあります。

2. GPUメモリの管理とリーク

PyTorchはGPUメモリを効率的に使用するためにキャッシュ機構を採用していますが、このキャッシュは完璧ではありません。

長時間の実行中に、小さなメモリリークが蓄積したり、メモリの断片化が進行したりします。

さらに、PyTorchのメモリ管理はアプリケーション層から詳細に制御することができません。
ざっくりとした解放命令やGC要求はできますが、それ以上の細かい制御はできずメモリの解放、予約領域の解放など簡単にはアプリ層からは触れず、あるいいみPyTorchまかせです。

2. CUDA非同期処理の特性

CUDAの多くの操作は非同期で行われるため、エラーが実際に発生した場所と報告される場所が異なることがあります。

エラーメッセージにも記載されている通り、実際のエラーは別のAPIコールでしれっと非同期的に報告されることがあります。

これによりデバッグがさらに困難になります。

3. 長時間実行の影響

商用サーバーアプリケーションは通常、数日から数週間(あるいはそれ以上)にわたって実行され続けます。

この間、小さな問題が徐々に蓄積し、最終的にはクリティカルなエラーとなって現れることがあります。

4. モデルの複雑性と負荷

当社サービスでも頻繁に実行される顔検出や画像認識などの複雑なモデルでは、大量のGPUリソースが必要とされ、長時間の高負荷状態がこの問題を引き起こす可能性が高まります。

実用的な対策

この問題に対処するための実践的なアプローチをいくつか紹介します

0.バージョンアップグレード前の長時間テスト

CUDAやPyTorchのバージョンをアップグレードする前に、必ず本番環境と同じ条件で長時間のテストを実施することが重要です。

特に注意すべき点は以下の通りです

  • 実際の負荷条件での検証 実際の運用時と同様の負荷をかけたテストを行います
  • 最低24時間の継続実行 メモリリークなどは時間経過とともに発生するため、短時間のテストでは発見できません
  • 繰り返しの処理 同じ処理を数千回繰り返すことで、安定性を確認します
# 最低でも24時間は同じ負荷で継続的に実行し、安定性を確認
for i in {1..10000}; do
    python your_processing_script.py --batch-size 32
    sleep 5
done
  • リソース使用量の監視 テスト中はGPUメモリやCPU使用率を継続的に監視し、徐々に増加する傾向がないか確認します
     このとき PyTorchやPythonの組み込み関数だけでなく、NVML(NVIDIA Management Library)を使用すて定期的に実行して監視するのがおすすめです。プロセス横断での使用メモリ量をより性格に取得することができます。
  • エラーログの監視 わずかな警告メッセージでも見逃さないようにログを注意深く監視します

互換性マトリックスの確認

PyTorchとCUDAのバージョン互換性を事前に確認します。PyTorch公式サイトには互換性マトリックスが公開されていますが、実際のアプリケーションでの互換性は環境によって異なることがあります。

当社ブログ「PyTorchがサポートするGPUの Compute Capability」 より

1. 運用面での対策

定期的な再起動の自動化

最も単純かつ効果的な対策は、サービスを定期的に再起動するスケジュールを設定することです。

# crontabの例: 毎日午前3時にサービスを再起動
0 3 * * * systemctl restart your_service

ヘルスチェックと自動再起動

定期的な再起動に加え、アプリケーションの状態を監視し、エラーが発生したら自動的に再起動するようにします

try:
    # メイン処理
    process_images()
except RuntimeError as e:
    if "CUDA error" in str(e):
        # ログ記録
        logging.error("CUDA error detected, restarting service")
        # プロセス再起動コード
        os.execv(sys.executable, ['python'] + sys.argv)

GPUリソースのモニタリング

NVML をつかってGPU使用率やメモリ消費を定期的に監視し、問題の予兆を検知します

import pynvml

def monitor_gpu():
    pynvml.nvmlInit()
    handle = pynvml.nvmlDeviceGetHandleByIndex(0)
    info = pynvml.nvmlDeviceGetMemoryInfo(handle)
    used_percent = info.used / info.total * 100
    
    # 使用率が90%を超えたら警告
    if used_percent > 90:
        logging.warning(f"GPU memory usage high: {used_percent:.2f}%")
        # 対策を実施 (キャッシュクリア、プロセス再起動など)

2. コード面での対策

コード面での一般的な対策も記載しておきましょう。
これは今回の根深い問題の処方箋ではありませんが、一般論としてご紹介いたします

CUDAキャッシュのクリア

定期的にPyTorchのCUDAキャッシュをクリアすることで、メモリリークの影響を減らすことができます

def clear_gpu_memory():
    torch.cuda.empty_cache()

# 一定回数の処理ごとにキャッシュクリア
for i, batch in enumerate(data_loader):
    process_batch(batch)
    if i % 100 == 0:
        clear_gpu_memory()

バッチサイズの最適化

こちらも一般論ですが、大きなバッチサイズはGPUメモリを圧迫します。より小さなバッチサイズを使用することで、メモリ問題を軽減できることがあります

# より小さなバッチサイズを設定
data_loader = DataLoader(dataset, batch_size=8, shuffle=True)

CPUフォールバックの実装

GPU処理に失敗した場合に自動的にCPUにフォールバックするロジックを実装すると、サービスの継続性が向上します

def process_with_fallback(image):
    try:
        # GPUで処理
        return process_on_gpu(image)
    except RuntimeError as e:
        if "CUDA error" in str(e):
            logging.warning("Falling back to CPU processing")
            # CPUで処理
            return process_on_cpu(image)
        else:
            raise

デバッグフラグの使用

エラーメッセージで推奨されているように、CUDA_LAUNCH_BLOCKING=1フラグを設定することで、非同期エラーの正確な位置を特定しやすくなります

CUDA_LAUNCH_BLOCKING=1 python your_script.py

3. アーキテクチャ面での対策

マイクロサービス化と水平スケーリング

モノリシックなアプリケーションを小さなマイクロサービスに分割することで、一部に問題が発生しても全体のサービスが継続できるようになります。

また、個別のサービスごとに再起動戦略を実装できます。

当社サービスも小さな単位でマイクロサービス化されており、同一の機能を提供するマイクロサービスが水平展開されています。マイクロサービスの定期的な再起動タイミングが重ならないようにスケジューリングすることでサービスの継続性を向上させることができます。

つまり複数のサーバーインスタンスを使用してロードバランシングすることで、一部のインスタンスが失敗しても、他のインスタンスがリクエストを処理できるようになります。

Kubernetes等のコンテナオーケストレーションツールを使用すると、こうした構成を効率的に管理できます。

まとめ

「CUDA error: unknown error」は、PyTorchとCUDAを使用した長時間実行サーバーでよく見られる問題です。

特にそれまでは安定していたのに、バージョンアップグレード後に突然発生することが多いため、事前の十分な検証と長時間テストが重要です。

この問題は完全に防ぐことは難しいものの、適切な運用戦略と予防策を組み合わせることで、その影響を最小限に抑えることができます。

バージョン互換性の慎重な検証、定期的な再起動の自動化、リソースモニタリング、コード最適化、適切なアーキテクチャ設計など、複数のアプローチを組み合わせて、信頼性の高いGPU対応サービスを構築することが重要です。

特に本番環境へのデプロイ前には、必ず数日間の安定性テストを行い、長時間実行時の問題を事前に発見することが、予期せぬダウンタイムを防ぐ鍵となります。

このような対策を導入することで、ディープラーニングやコンピュータビジョンのサーバーアプリケーションを、より安定して運用することができるでしょう。

また、当社ではGPU商用サービスをご検討中または、商用サービス運用中でお悩みをお持ちの事業者様へのGPUテクニカルコンサルティング・アドバイザリーのご提供も行っておりますので、お気軽にご相談くださいませ。

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 プロダクト開発部