5 ポイント 投稿者 GN⁺ 2025-05-17 | 1件のコメント | WhatsAppで共有
  • フリースレッドPythonは、マルチコアハードウェアを効率的に活用できるよう設計されている
  • CPython 3.14では、コアモジュールのスレッドセーフ性と性能が大幅に改善された
  • 依然としてフリースレッドビルドをサポートしていない主要パッケージが数多く残っている
  • 実運用環境でのレポートやコミュニティへの貢献を通じて、誰でも発展に参加できる

概要

先週、CPython 3.14.0b1が公開され、今週はPyCon 2025がピッツバーグで始まる。
この2つの出来事は、フリースレッドPythonの配布と安定化の両面で重要な節目となる。
本稿では過去1年間の歩みを振り返り、Quansightチームが複雑な依存関係を持つ実際の本番ワークフローにフリースレッドビルドを試験的に適用するうえで、どのように中核的な役割を果たしてきたかを説明する。

フリースレッドPythonの意味と必要性

  • フリースレッドPythonのサポートにより、マルチコアCPUやGPUが一般化した現代のハードウェアにおける計算資源全体の活用が可能になる
  • **従来のGIL(グローバルインタプリタロック)**方式では、並列アルゴリズムを十分に活用するには回避策や個別のチューニングが必要だった
  • 通常はthreadingモジュールよりmultiprocessingが使われてきたが、こちらはプロセス生成コストが大きく、データコピーも非効率である
  • Pythonパッケージのうちネイティブコードを含むものは、フリースレッドビルドとそのまま互換になるわけではないため、スレッドセーフ性の保証に向けたコード監査が不可欠である
  • GILの解除にはCPythonインタプリタに深い構造的変更が必要であり、既存パッケージに潜む構造上の問題をあぶり出すきっかけにもなった

主な成果

  • MetaのPythonランタイムチームとともに、以下のようなさまざまなパッケージやプロジェクトにフリースレッドPython対応を貢献してきた
    • meson、meson-python、setup-python GitHub Actions、packaging、pip、setuptools などのパッケージングおよびワークフローツール
    • Cython、pybind11、f2py、PyO3 などのバインディング生成ツール
    • NumPy、SciPy、PyArrow、Matplotlib、pandas、scikit-learn、scikit-image などのPyDataエコシステムの中核パッケージ
    • Pillow、PyYAML、yarl、multidict、frozenlist などのPyPIダウンロード上位の主要依存パッケージ
  • まだ対応していない人気パッケージ群(CFFI、cryptography、PyNaCl、aiohttp、SQLAlchemy、grpcio など)や機械学習ライブラリ(safetensors、tokenizers など)についても、段階的に作業が進められている
  • QuansightチームのCPythonコア開発者は、3.14版に以下のような改善を反映した
    • warningsモジュールがフリースレッドビルドでデフォルトでスレッドセーフに動作するようになった
    • asyncioの深刻なスレッドセーフ性の問題を改善し、並列スケーラビリティも向上
    • ctypesモジュールのスレッドセーフ性を全面的に改善
    • フリースレッドガベージコレクタの性能向上
    • deferred reference counting方式および適応的特殊化インタプリタの最適化
    • 数多くのバグ修正とスレッドセーフ性の補強を実施
  • フリースレッドPython対応のための総合ガイド1も作成され、今後さらに多くのパッケージで実践的に参照できるドキュメントが提供された

フリースレッドPythonエコシステムの現状

  • 1年前(3.13.0b1リリース時点)には、フリースレッドビルド上でほとんどのPythonパッケージのインストールが全面的に壊れている状態だった
  • ビルド失敗の原因は根本的な問題というより、未対応のデフォルトオプションや小さな前提が崩れたことによるものだった
  • この1年、コミュニティと協力して多くの問題を解決してきており、特にCython 3.1.0の公式サポートは大きな転換点となった
  • 依然として、コンパイル済みコードを含みながらフリースレッド用ホイールを提供していないパッケージが残っている
    それらの進捗は手動および自動の追跡テーブル2で確認できる

当面の課題

  • 現在のフリースレッドPythonビルドは、実際のワークフローでの実験とフィードバックを必要とする段階にある
  • マルチプロセシング利用のコストが大きいワークフローでは、特に性能改善の可能性がある一方、各パッケージに対する綿密なスレッドセーフ性監査が不可欠である
  • 多くのライブラリはミュータブルなデータ構造を提供していながら、スレッドセーフ性の文書化や実際の安全保証が不十分である
  • パッケージ規模が大きくレガシーが多い場合、コード全体を十分に把握できる人が不足し、対応が遅れる現象が生じている
  • コミュニティ全体として、中核パッケージ保守の持続可能性に向けた取り組みが必要である

貢献方法

  • 公式ガイド貢献ガイドを参照できる
  • エコシステム全体の課題追跡や主要な互換性ドキュメントは、free-threaded-compatibilityリポジトリ5で管理されている
  • Quansight-Labs主催のコミュニティDiscord6で議論への参加や貢献が可能である

PyConでの発表予定

  • 本文の著者とチームメンバーのLysandros NikolaouPyCon 2025で発表する予定である
  • 経験に基づく実践的な移植事例やノウハウを共有する計画であり、YouTubeの録画映像も提供予定である
  • フリースレッドビルドはPython言語の未来だと信じており、その実現に貢献できることに大きな期待を寄せている
  • 今日の取り組みが、日々数百万人の開発者が使う多様で膨大なパッケージの未来を切り開く転換点になることを願っている

1件のコメント

 
GN⁺ 2025-05-17
Hacker News の意見
  • 多くの人がマルチプロセシングを使っているが、プロセス生成コストが高い点への言及

    • SharedMemory 機能が存在するのに、なぜもっと頻繁に使われないのか理解できない

    • ShareableList の使用体験が良かった点を強調

    • Unix でのプロセス生成速度は 1ms 未満レベル

      • ただし Python インタープリタのプロセス起動は import の数に応じて 30ms〜300ms かかることがある
      • 1〜2桁の差があるため、正確な数値が重要
      • CGI はこの点で例外であり、C・Rust・Go では問題にならない
      • sqlite.org でもリクエストごとに個別プロセス方式を使っているという例を共有
    • ShareableList では共有できるのは atomic なスカラーと bytes・文字列だけ

      • Python の構造化オブジェクトでは、pickle dump などのシリアライズコストやプロセスごとのメモリ複製コストが発生する
    • numpy 配列の共有で大きな成功体験がある

      • 明示的共有方式は、スレッド間でうっかり共有して発生する問題のデバッグ難易度と比べれば負担ではない
      • 多くの人が、スレッドがマルチプロセシングよりどれほど優れているかを過大評価している
      • GIL が解放されると、ランダムな segfault のデバッグが増えるのではないかと心配
      • JavaScript が共有メモリベースのスレッディングをサポートしていないことに、人々がそれほど強く不満を言ってこなかった点に言及
      • JavaScript は十分高速なので、その必要性が低いのではという解釈
      • Python の基本性能改善にもっと力を入れてほしいという期待
    • プロセスは独立して死ぬため、ロックを保持したまま共有メモリのデータ構造を変更中だったプロセスが死ぬと復旧が難しいという点

      • Postgres の共有メモリ構造と、バックエンドプロセス全体の終了が必要になる例を提示
      • スレッドはまとめて死ぬ構造なので、こうした問題の発生があまり意識されないという点
    • 共有メモリは専用ハードウェア上でしか動作しない

      • AWS Fargate のような環境では共有メモリがなく、ネットワークまたはファイルシステムを使う必要があるためレイテンシが増える
      • fork 方式のプロセス複製にはまた別の問題がある
      • 実体験では green thread と actor モデルの方がはるかに効果的だったという主張
  • GIL 削除が Python のマルチスレッドコードに、並列処理以外の影響もあるのか気になる

    • GIL が維持されてきた理由は、マルチスレッドが GIL に依存していたからではなく、GIL の削除がインタープリタ実装や C 拡張、単一スレッドコードの速度低下を招くためだという理解

    • Free-threaded Python が、バイトコード境界でいつでもプリエンプトされうるという従来の保証と同じなのか気になる

    • それともロックをより多く使う必要があるなど、書き方が変わるのか気になる

    • free-threaded Python でも大半は同じ保証

      • ただし free-threading がないと、人々はスレッディング機能をあまり使わず、境界でプリエンプトされるバグも現実にはあまり発生しない
      • free-threading 導入でより多くのバグが露出する
      • マルチプロセス回避策を使う必要がなくなり、ユーザーコードは単純になる;インタープリタの複雑化には十分な価値があると思う
      • C 拡張の複雑化は free-threading より sub-interpreter の方が深刻;numpy チームは sub-interpreter はサポートできないと明言している
      • numpy はすでに free-threading をサポートしており、残るバグを修正中
      • 単一スレッド性能がわずかに(1桁 %)遅くなるのは受け入れ可能なトレードオフ
    • マルチコア利用は可能になるが、スレッドごとの性能低下とライブラリの再作業が必要

      • PyTorch で試したところ、CPU 使用量は 10 倍でも仕事のスループットは半分だった経験
      • 時間とともに改善を期待しており、20 年間これを待ってきたので歓迎している
    • 競合状態(race condition)がより頻繁に起きうるので、信頼性を確保するにはマルチスレッド Python を書く際により注意が必要

  • Microsoft が Faster Python チームを解散したという話

    • 2025 年の予想実績未達でチームを維持できなかったということ

    • 今後も CPython に性能改善が追加されるのか、あるいは他社が支援するのか見守るつもり

    • Facebook(Meta)はまだ一部支援しているようだ

    • Microsoft の約束に比べてスケジュールが大幅に遅れていた点に言及

      • 最近は深刻な政治・ガバナンス問題を把握しているはずで、有能な社員がわざわざ貢献して集団から中傷されたいとは思わないだろうという意見
      • CPython 組織は約束過多で、従順な人に仕事を集中させ、有能な反対者を追い出しているという批判
      • 昔はこうした問題はなく、今は自ら招いた問題だという見方
    • この結果は残念だが、Microsoft の長期的な約束を信じていなかった自分の予想が当たったとの言及

    • 最近 Google も Python 開発チーム全体を解雇したようだという噂

      • 両方に時代的背景や共通要因があるのか気になる
    • 非常に残念だが、embrace & extend の後に残るものはひとつしかない、という含み

  • Python から GIL がなくなることを心配しているのは自分だけなのか気になる

    • どの言語でも複雑なマルチスレッドコードは信頼しにくく、Python は動的な特性上とくに不安だ

    • 変化への恐れを抱いているのは自分だけではなく、その根拠が非合理的である可能性もあるという点

      • GIL は純粋な技術的負債なので、コミュニティの利益のために削除が必要
      • 最近の Python ではたいていスレッドの代わりに non blocking IO と async が使われている
      • スレッドを使わなければ GIL 削除による変化はない;C ライブラリも単一スレッドなら安全
      • 実際にスレッドを使う場合だけ注意が必要
      • ナイーブなスレッド Python コードはこれまで GIL によって単一スレッドのように動いていたが、これからは少し速くなる一方で、バグは増えるかもしれない
      • 解決策はスレッドを使わないか、使うならきちんと学ぶことだという助言
      • 今後はより良い抽象化が提供されるはずで、コミュニティで structured concurrency などの議論が進むことに期待
    • 自分は asyncio を積極的に使っている

      • シングルスレッドだが concurrent な Python を楽しく書ける;Node.js のように使える
      • Web・ネットワーク処理にはこうした方式を勧めたい
    • ML/AI 分野のように、専門家が先に複雑なライブラリを作り、一般ユーザーにはそれを届ける構図になると予想

      • Python の GIL が深刻なボトルネックになるケースが増えている
      • そのため Go 言語を学んだ;スレッド対応がきちんとしていて、Python より低レベル、C/C++ よりは高い抽象化を持つと言える
      • コンパイラ方式もスレッディングに劣らず重要な背景
    • 無用な不安を煽るだけかもしれないが、LLM がここ数十年の GIL 存在を前提にした Python コードで学習されている事実を思い出させる

    • GIL の有無はマルチコア処理を望む人にだけ関係する

      • 現時点でもスレッディングやマルチプロセシングを気にしていなかったなら、実質的な変化はない
      • race condition の問題は GIL の有無に関係なく発生する
  • Python をよく使うが専門家ではなく、ときどき concurrent.futures で単純な関数を複数同時実行する程度

    • こういうユーザーは今後何を変えるべきか気になる

    • スレッドが GIL に縛られなくなるので全体的に速くなる

      • 共有オブジェクトのロック処理さえ適切なら、追加で心配する必要はない
  • 20 年間 Python でプロとして開発してきた経験からの所感

    • スレッドが本当に必要なのは、メッセージパッシングが避けられない場合に限られる

      • Python エコシステムはすでにこうした状況すべてへの回避策を提供している
      • 複数スレッド処理の落とし穴(ロックなど)が多いため、今後も特定のライブラリ・ドメインでのみ必要かもしれない
      • 純粋な Python だけで最大限の性能を出したいなら、native code ベースのライブラリ(例: Pypy, numba)も活用できる
      • Python の性能面での革命は結局 async プログラミングであり、ぜひ学んでみてほしい
    • 自分も同じくらい長く Python を使ってきて同意するが、少し違う言い方をしたい

      • Python スレッドの出来があまりに悪かったため、それを避けるためのさまざまな回避策が発達した
      • CPU-bound な処理をスレッドで 2 倍速くしようとして GIL 問題にぶつかり、マルチプロセシングに切り替えたが、データ構造のシリアライズによるコストが生じ、2 倍のコアで 1.5 倍の速度といった非効率を経験した
      • 良いスレッドサポートがあれば活用したい環境は多い;これまで存在しなかったので各種の代替アプローチを使ってきたという点
      • 状況に合うなら async の活用を強く勧める(glyph、あなたの言う通りでした!)
  • AI 画像だが、ヘビに尻尾が 2 本あるように見えるのが不思議

    • そっと流しておこうという相づち;Python の記事にヘビの絵が入っていたら、たいていは特に気にする価値のない合図だ、という冗談めいた言及

    • 「Confusoborus」という冗談っぽい名称を提案

  • ヘッダー画像のヘビが 2 本の尻尾を持っているようだという指摘

    • 同じプロセス内で 2 本目のスレッドを生成した姿なのだろう、という冗談
  • ライブラリサポート以外に、WSGI と Celery ワーカーを単一プロセスで立ち上げることに別の制約があるのか気になる

    • 制約はないが、こうしたやり方が言語の第一級機能ではないという点
      • GIL は技術的負債の問題だという説明
      • 並列性以外にも GIL 解放が必要な要素がある
  • 今後の性能時代に向けた、とてつもない基盤整備だと思う