PyTorch、AI エージェントを活用したモデル初期対応の加速手法を公開
本文の状態
日本語全文を表示中
詳細モードで約25分の本文を読めます。
同じ出来事の情報源
この情報源を基点に整理
PyTorch Blog
PyTorch Blog は、AI エージェントを活用して新しいモデルやハードウェアへの対応を自動化する手法を示し、IBM の Spyre AI アクセラレータ上で HuggingFace の数千のモデルを実行可能にする成果を発表した。
AI深層分析を開く2026年8月21日 10:41
AI深層分析
キーポイント
モデルとソフトウェアスタックのギャップ拡大
新アーキテクチャやオペレーションが次々と登場する中、既存のコンパイルスタックやハードウェア対応が遅れがちであり、特に新ハードではこのギャップが顕著になる。
AI エージェントによる自動イネーブルメント
従来の専門家による手作業に代わり、AI エージェントがアダプタを生成することで、モデルワークフローとコンパイルスタックの橋渡しを行い、対応期間を大幅に短縮する。
IBM Spyre での実証実験
少数の AI 生成アダプタのみで HuggingFace Transformers の標準モデルを IBM の Spyre AI アクセラレータ上で実行し、数千のモデルに対する完全なイネーブルメントを実現した。
並行開発によるスピード向上
プラットフォームが完成するのを待たず、実際のモデルの実行を並行して進めることで、ハードウェアとソフトウェアの双方の進化に柔軟に対応できる体制を提案している。
アダプターによるモデルとスタックの橋渡し
アダプターはランタイムパッチとして機能し、基盤のギャップが完全に解消される前に既存モデルを実行可能にする。これは特定の演算を等価なもので置換する手法であり、計算結果や数学的整合性は維持される。
重要な引用
Extending stack enablement to each new family has traditionally been slow, specialist work that delays deployment.
Enablement can't wait for the stack to be complete; it should progress in parallel, letting real models run while the platform underneath them matures.
An adapter isn't a hand-optimized kernel – it hands the stack a form it can lower well, but performance remains the compiler's responsibility.
Adapters play the same role. An individual adapter is usually transitional: its job is to carry a model across one specific gap in the stack as it stands today, and it is designed to be removed once that gap is closed.
編集コメントを表示
編集コメント
モデルとハードウェアの進化速度差を埋めるための自動化アプローチは、実務現場の課題解決に直結する重要な知見である。特に新アクセラレータの早期活用において、AI エージェントによるアダプタ生成が有効な手段となり得ることを示している。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
TL;DR
AI モデルの状況は常に変化し続けており、それを実行するソフトウェアスタックは常に一歩遅れをとっています。成熟したコンパイルスタックであっても、新しいモデルファミリーが登場すると、既存のコンパイラが対応できない独自のモジュールが含まれていることがよくあります。特に新ハードウェアでは、未熟なスタックと生態系全体が同時に直面するため、そのギャップはさらに大きくなります。
従来、各新しいモデルファミリーへのスタック対応は専門家の手による遅々とした作業であり、デプロイを妨げる要因となってきました。本ブログ記事では、AI エージェントを活用して、特定のモデルやエコシステム全体の Day-One(初日)対応を可能にする手法を紹介します。具体的には、モデルのワークフローとコンパイルスタックの間を橋渡しすることで実現します。
このアプローチの有効性を、より困難なケースで実証しました。わずか数個の AI によって生成されたアダプターを用いることで、IBM の Spyre AI アクセラレーター上で標準的な HuggingFace Transformers モデルを実行可能にし、数千ものモデルに対する完全な対応を達成しています。
課題:変化するモデル状況への追従
モデルの状況は常に変化し続けています。新しいアーキテクチャやチェックポイントが次々と登場しており、それぞれが特定の演算、形状、数値範囲の組み合わせとして構成されています。しかし、それらを実行するソフトウェアは常に一歩遅れをとっています。
最も成熟し広く展開されているスタックであっても、新たに登場したモデルファミリーには、既存のソフトウェアがまだきれいに処理できない独自のモジュールや、融合されたアテンション変種、あるいは未対応の数値範囲が含まれていることがよくあります。
imageHuggingFace Transformers ライブラリに随時追加される新しいモデルファミリー。各ステップは、主要なモデルファミリーが統合されたタイミングを示しており、新たなアーキテクチャが着実に、かつ加速度的に登場している様子を物語っています。
あらゆるデバイスでモデルを実行するには、それをハードウェアのコアやメモリ階層、数値形式にマッピングするソフトウェアスタックが必要です。具体的にはコンパイラ、オペレータの低級変換(lowerings)のセット、そしてランタイムがそれです。このスタックは大きくて進化し続けるソフトウェアであり、新しいアーキテクチャが登場すると、まだ成熟していない領域を突くことになります。その未整備な領域が整うまで、モデルは実行できないか、あるいはうまく動作しません。こうしたギャップを埋めるには、従来は専門家の手による数週間から数ヶ月の作業が必要でした。
このギャップが最も顕著になるのは、新しいハードウェアが登場した時です。新しいアクセラレータは単なるチップではなく、さまざまなモデルのニーズに応えるためにまだ成長途中にある若いスタックを伴って出荷されます。ここでは成熟したスタックに一つの新しいモデルがぶつかるのではなく、構築中のスタックに対して生態系全体としてのモデル群が向かい合うことになります。さらに、その上に新たなアーキテクチャが次々と登場する中で、スタックも同時に進化し続ける必要があります。イネーブルメント(機能実現)は、スタックの完成を待っていてはいけません。プラットフォームが成熟する間も並行して進め、実モデルを実行させながら基盤を整えていくべきです。
image AI アクセラレータのリリース。各ドットは新しいチップの発表日を示しています。新しいハードウェアは、新しいモデルが次々と登場するのと同じペースで現れています。そして、すべてのチップアーキテクチャには、継続的に進化し続けるソフトウェアスタックが必要です。
新しいハードウェアはその極端なケースですが、課題はより一般的です。成熟したスタックであっても、新規のスタックであっても、ソフトウェアをモデルの動向に合わせて維持していくことが求められます。以下では、このギャップを埋めるための戦略と、IBM の Spyre アクセラレータ上で標準的な HuggingFace Transformers モデルを実行する具体的な事例を通じて、その実装を示します。
戦略:モデルとスタックをつなぐアダプター
ここで紹介する戦略は、ランタイムパッチである「アダプター」という薄いレイヤーです。これにより、スタック内のすべてのギャップが解消されるのを待たずに、既存のモデルを特定のプラットフォームで今日から実行可能にします。前提として、プラットフォーム側には PyTorch コンパイラが用意されており、これを下位レベルへ変換する機能を提供していると仮定しています。
通常の Torch コードにおけるコアテンソル演算、つまり行列乗算や要素ごとの演算、そして集約処理などをターゲットハードウェアにマッピングすることで、モデルのロジックの大部分が変更されることなく実行されます。モデル内の一部の演算がまだスタックをスムーズに通る経路を持っていない場合、アダプターはランタイムで介入し、同等でありながら適切な経路を持つ演算と置き換えます。
パッチはデバイスに対するモデルの表現方法を変更しますが、計算内容そのものには影響しません。背後にある数学的処理はそのまま保たれます。アダプターが手動最適化されたカーネルであるわけではありません。これはスタックに対して効率的に lowered できる形式を提供するものであり、パフォーマンスの責任は依然としてコンパイラにあります。
スタックの状態を待機してブロックするのではなく、アダプターは現在のスタックを実用的な架け橋として機能させます。これを理解するための有用な比喩が、大規模な建設プロジェクトです。建設中の建物、あるいは建設中であるか改修工事中の建物の周囲には、必ず何らかの足場が存在します。これは作業が進んでいない部分で作業を継続させるための一時的なアクセス用スロープや支持梁のようなものです。足場のどの一部も永続的なものではなく、背後にある構造物が自立できるようになれば、それぞれの足場は撤去されます。
アダプターは同じ役割を果たします。個々のアダプターは通常、一時的なものです。その仕事は、現在のスタックにおける特定のギャップをモデルが横断できるようにすることであり、そのギャップが埋まれば取り外すことを前提に設計されています。プラットフォームが成熟し、新しい最適化が統合され、より多くのアーキテクチャがサポートされ、恒久的な経路がその下に開かれるからです。
ただし、すべてのアダプターが撤去されるわけではありません。スタックが最終的に埋める一時的なギャップを橋渡しするものもあれば、ターゲットハードウェアに本質的で永続的な違いがあるために存在し続けるものもあります。特にアクセラレータのハードウェアに独自のアーキテクチャがある場合、それらのブリッジは恒久的に残されることになります。
しかし、アダプター層そのものは、個々のアダプターとは異なり、永続的な性質を持っています。モデルの状況は常に移り変わるため、スタックがまだ追いついていない新たなギャップが必ず生まれます。古い足場が取り外されても、別の場所で新しい足場が構築され続けるのです。この層は、並行して進化している2つのものを結びつけます。一方はモデルエコシステムで、私たちの場合は HuggingFace Transformers です。安定した API と膨大なコミュニティを持つ数千のモデルが存在します。他方はプラットフォームのハードウェアを抽象化するスタックで、私たちの場合は Spyre です。これはモデルをアクセラレータデバイスにマッピングするコンパイラおよびランタイムスタックであり、継続的な開発が行われています。アダプターはその間に位置し、両端が進化を続ける間も、モデルがハードウェア上で実行できるように支えています。
この戦略を数千ものモデル規模で実用化できる背景には AI の存在があります。従来、新しいモデルファミリーの対応は専門家の手による遅い作業であり、ハードウェアプラットフォームやチップアーキテクチャごとに多大な労力を要していました。コーディングエージェントはこの経済構造を変え、かつては個別対応だった作業を、エコシステム全体に追いつくスピードで実行可能なものに変えています。
本稿ではその具体的な仕組みを紹介しますが、まずはこの戦略を実装するプラットフォームについて説明します。
プラットフォーム:Spyre と torch-spyre
例として取り上げるハードウェアは、IBM の AI アクセラレータ「Spyre」です。これは AIU(Artificial Intelligence Unit)を基盤に構築されています。多数のコアが高帯域幅のリングで接続され、それぞれが独自のローカルスクラッチパッドメモリと処理要素配列を持っています。これらの要素がモデルの中核となる行列乗算を実行します。
Spyre にはいくつかの特徴があります。第一に、データフロー駆動型である点です。計算は計算エンジンへデータが到着した際にトリガーされ、逐次的な制御フローによるボトルネックを解消し、モデルの構造化された反復的な数学演算に対してハードウェアを常に稼働させます。これは、スケジュールされたスレッドグループに対して明示的な命令ストリームとしてカーネルを実行する従来の GPU とは対照的です。
第二に、推論用に設計された低精度数値形式を採用している点です。これにより、低消費電力で高いスループットを実現しています。
Spyre のメモリと演算は、"sticks" と呼ばれる固定サイズのチャンク(128 バイト、あるいは fp16 で 64 値)上で動作します。また、テンソルの次元は stick の境界に合わせて配置されることを前提としています(Tiled Tensors RFC を参照)。これは、PyTorch やモデルコードが想定する契約とは異なります。PyTorch ではテンソルは任意の形状を持つ平坦な配列であり、メモリへのマッピング方法はフレームワークが隠蔽しています。一方、モデルアーキテクチャは統計的・モデル化上の理由からヘッド次元やシーケンス長、語彙サイズを選定しますが、"stick" の概念はありません。そのため、今回のシナリオではアダプターの役割の一部として、HF Transformers モデルの実装と PyTorch 内の Spyre コンパイラ拡張の間に橋渡しを行い、両者の視点を統合する必要があります。
このモデルをハードウェアにマッピングするソフトウェアスタックは "torch-spyre" です。これは PyTorch のバックエンドであり、通常の torch コードを Spyre でコンパイルして実行します。具体的には、モデルがハードウェアで実行可能なプランへと変換されます。また、前節で述べた一時的な足場となるアダプターは、私たちが "HF-adapters" と名付けたプロジェクトです。これは、既存の HuggingFace モデルを今日から Spyre で動作させるためのランタイムパッチです。
AI がアダプター構築にどう役立つか
アダプターは、2 つのコードベースの隙間に存在します。一方には、Transformer が表現するモデルがあります——モジュールやアテンションブロック、特定のアーキテクチャが RoPE とノルムをどのように接続しているかという仕組みです。他方には、torch-spyre があります。これは計算をデバイス上に下位化するコンパイラとランタイムです。
アダプターを作成するには、両方の側面を同時に理解し、まだ交わっていない正確な場所を見つける必要があります。それは、モデルが特定の形式で表現する演算を、コンパイラがきれいに下位化できないケースです。実際には、これはモデルの内部ロジックを追跡しながら、その各部分がコンパイルスタックをどのように流れるかを追うことを意味します。これが AI によって変容した作業の一部です。
コーディングエージェントは、単一のモジュールからアテンションブロックを経て完全なフォワードパスに至るまで、Transformer モデルの内部ロジックをあらゆるレベルで追跡できるようになりました。また、torch-spyre の下位化ロジックを通じて同じ計算を追跡し、ハードウェア上でどのように実行されるべきかを確認することも可能です。
この 2 つの視点(モデル側とデバイス側)を同時に保持することが、本作業のコアループを可能にします。具体的には、スタック内の隙間を特定し、その隙間を越えてモデルを運ぶ高レベルのパッチ草案を作成するというサイクルです。通常、モデル側の情報とデバイス側の情報は、異なる場所、異なる言語、異なる抽象度で文書化されています。これらを読み込み、素早く相互参照することが、かつてはこのような試みを実践不可能にするボトルネックでした。

この仕組みが実際に機能する背景には、いくつかの重要な要素があります。まず、ハードウェアとソフトウェアスタックの変化を追跡し続けるナレッジベースを維持しています。これにより、エージェントは一般的な仮説ではなく、Spyre の実際の挙動に基づいて推論を行うことができます。
さらに、HuggingFace Transformers ライブラリと torch-spyre バックエンドの両方について、ソースコードや GitHub リポジトリへの直接アクセス権限を与えています。これによって、実際のコード、課題(issues)、プルリクエストを通じてロジックを追跡することが可能になります。
また、最先端のモデルはすでに機械学習やトランスフォーマーアーキテクチャに関する深い知識を備えています。リポジトリを開く前から、アテンション(attention)、RoPE、RMSNorm といった概念を理解しているため、学習プロセスはゼロから始めるのではなく、理解した状態からスタートできます。
重要なのは、追加するアダプター一つひとつが、「どの適応策がなぜ有効だったか」を記録している点です。新しいモデルが登場しても、それは完全に未知の問題というよりは、すでに導入済みのアーキテクチャの派生型であるケースがほとんどです。そのため、既存のアダプターは模範となるテンプレートであると同時に、そのまま再利用できるパッチの源としても機能します。
その結果、対応するモデルが増えるほど、類似した次世代モデルへの対応コストは低下し、新しいアダプターの追加も時間とともに容易になっていきます。以下のチャートが示す通り、数ヶ月かけて少数の異なるアダプターを追加していくだけで、対象セット内のモデルの大半をカバーできるようになります。
image2026 年 4 月中旬から 6 月末にかけての、対象モデルセットのカバレッジ状況です。左軸は埋め込みモデル(embedding models)の数、右軸は個別のアダプター(adapters)の数を示しています。
最終スナップショットでは、10,000 本以上のダウンロード数がある Hugging Face の埋め込みモデルのうち、7,960 本を 13 種類の異なるアダプターがカバーしており、そのうち 6,804 本が Spyre でのエンドツーエンドテストに合格しています。
カバレッジの推移は、モデルを一つずつ追加していくのではなく、数回の大きなステップで上昇します。これは、新規に登場するモデルの多くが、すでに実装済みのアーキテクチャをベースにした派生型であるためです。新しいアダプターを導入することで、類似したモデル群全体を一度にカバーできるようになります。
この取り組みの規模は、対象となるアーキテクチャの数と、それによって獲得できるモデルのカバレッジ数に応じて拡大します。2 つのカバレッジ曲線の間のギャップ(「アダプターが存在するモデル」と「Spyre でテストに合格するモデル」の差)が示すのは、デバッグの難しさです。アダプターの導入は必要条件ですが、それだけでは不十分であり、このギャップを埋めるために、後述する人間による診断プロセスに多くのリソースが投入されています。
同時に、人間の専門知識と監督も不可欠です。特に以下の 2 つの失敗モードが頻繁に発生します。
まず、ローカライズ自体が非常に困難であるという点です。CPU や GPU では正しく動作するモデルが、デバイス上では誤った出力を生成してしまう場合、その誤りの原因となる箇所を特定するのは、コードを一度読むだけでは到底できません。
重要なのは、モデルの異なる部分を単独でテストする場合と、組み合わせてテストする場合の両方で再現性を確認することです。特定のブロックだけを切り出して個別に検証し、その後再び元の構成に戻して、周囲の計算処理の中でその不具合が持続するかどうかを確認します。なぜなら、問題の原因は特定の演算一つにあるのではなく、それらの相互作用の中にあり、そこで生じるわずかな忠実度のズレが、下流のコンポーネントによってたまたま増幅される形で現れるからです。
元のコードと適応後のコードを同じ CPU や GPU で実行する場合、ビット単位で完全に一致する出力が得られることを期待します。これはアダプターが計算内容を正しく保持していることの裏付けとなります。しかし、この「ビット単位の決定性」への期待は、ターゲットハードウェアには適用できません。そこでは数値的なドリフト(誤差のズレ)が発生することがあり、それが本来のローワーリングエラーなのかを区別するのが難しい場合があります。
さらに、コンパイラが各演算を独立して処理するのではなく、隣接する演算同士を融合させるため、ローカライズの難易度は高まります。どの演算を融合させるかは、その演算が存在する文脈に依存します。単独で存在するときはある方法でローワーリングされる演算も、周囲の演算と融合した場合は異なる方法で処理されます。つまり、切り出してテストした時点では忠実であるように見えた演算でも、融合が変更されたことで本来の位置では誤動作を引き起こす可能性があります。
これは忍耐強く、方法論に基づいた作業であり、単一の自動プローブで代替できるものではありません。
第二に、エージェントは標的実験から誤った結論を導き出すことがよくあります。モデルの内部深くにある大きな数値的な不一致は、決定的な証拠ではなく、手がかりに過ぎません。人間もエージェントも同様に、中間テンソルにおける驚くべき差異を見つけ、「これがエンドツーエンドの失敗の原因だ」と結論付けるのは容易です。しかし、下流の層では内部的なエラーが通常減衰し、最終出力に至る前に消えてしまうため、あるコンポーネントは壊れているように見えても、最終結果には全く無害であるケースがあります。
真の診断と単なる推測を分けるのは、「不一致を実際の出力まで追跡する」「エンドツーエンドの結果と矛盾するプローブを疑う」「変更したものが本当に重要だった要素であることを確認する」という判断力です。これは、エージェントが単独で信頼性を持って提供できるものではありません。エージェントは示唆的な実験一つから自信満々な説明を提案しますが、それが成立するかは人間が検証する必要があります。
この役割分担は自然な流れから導かれます。AI は、2 つの巨大なコードベースを同時に読み込み、アーキテクチャを認識し、過去の事例を類推して最初のアダプターを作成するといった、広範囲で反復的な照合作業を担当します。一方、人間の専門家は診断役を果たします。デバイス上でしか発生しない目に見えない不具合を特定し、最終的なエンドツーエンドテストに合格するまで、どのリードも安易には信頼しません。
もう一つの重要な役割は、エージェントが過去の失敗から何を学ぶべきかを人間が決めることです。アダプターの作成やデバッグ時に従う手順を更新したり、単発の問題と、記録して価値のある反復的な「落とし穴」を分離したりします。これらはエージェントのスキルやメモリとして記録され、プロセスの効率化に寄与しますが、人間の明示的な監督が必要なくなるわけではありません。
アダプターを検証ツールとして活用する
各アダプターは、単にモデルをデバイス上に展開するだけでなく、その過程で基盤となるスタックのどこがまだ改善を要しているかを明確に浮き彫りにします。
これは、成熟したエコシステムと未熟なスタックをつなぐ際に生じる一般的な性質です。そのようなスタックにおける課題は、単一の操作に存在するのではなく、ユニットテストでは想定されていなかった組み合わせの中に潜んでいます。これらを表面化させる唯一の確実な方法は、信頼できるリファレンスに対して実際のワークフローを最初から最後まで実行することです。アダプターがあれば、スタックが完成する前であってもそれが可能になります。つまり、各アダプターが運ぶモデルは、プラットフォームに対する負荷テストとしても機能するのです。
Torch-Spyre チームの例では、主にソフトウェアスタックの下位層——コンパイラ、オペレータの低級変換(lowerings)、デバイスへの作業配置を行うランタイム——で活動しています。このレベルでは、実際のモデルがどのように振る舞うかを予測するのは非常に困難です。
本番環境のモデルは、特定の形状、オペレータ、重みレイアウト、数値範囲の組み合わせによって構成されています。スタック上のギャップに引っかかる原因となるのは、単一の要素ではなく、この特有の組み合わせであることがほとんどです。これらのギャップは確かに存在しますが、スタックの下層から見るとそれらはほとんど目に見えません。単一の低級変換を見ただけでは、どのモデルのどのレイヤーで、どのような入力によってそれが実際に引き起こされるのかを知ることはできません。
HuggingFace の標準モデルをエンドツーエンドで実行することで、こうしたギャップが可視化されます。CPU/GPU 参照実装との間で生じるエンドツーエンドでの乖離は、プラットフォーム内のどこかに注意が必要な問題があることを示す強力なシグナルです。実際には表面化する問題は、いくつかの繰り返し現れるカテゴリに分類できます。
- 対応していない低級変換パス:個々のオペレータが単独では動作しているにもかかわらず、スタック全体としてブロックや融合された形状をまだ処理できないケース。
- デバイス固有の数値挙動:CPU/GPU 参照実装では有限の値であるものが、デバイス上ではオーバーフローしたり NaN に変換されたりする現象。
- アライメントとパディングの前提条件:ハードウェアが想定している形状と一致しない場合に、結果を静かに破損させるケース。
これらに共通するのは、大規模な融合依存性です。モデル全体をコンパイルすると、スタックは異なる演算や形状を結合したカーネルへと統合します。どの要素が融合されるかは、周囲のグラフ構造によって決定されます。そのため、ある演算子が単体では低レベルテストに合格しても、ここでは失敗することがあります。その失敗の原因は、裸の演算子自体ではなく、融合された文脈にあります。
実際のモデルには、実データが伴います。低レベルのテストでは通常、演算子に対してランダムなテンソルを供給しますが、学習済みの重みやそれらが生成する活性化値には、ランダム入力にはない構造的な特徴があります。具体的には、特定の値の範囲やほぼ一定の行、稀に現れる大きな外れ値などです。この構造こそが、カーネルをオーバーフローや NaN(数値非該当)へと押しやる要因となることがよくあります。したがって、これら問題の性質は、演算子単位のテストからは決して明らかになりません。それらは、モデル全体が実際の重みと活性化値をスタックを通じて処理する際に初めて顕在化するのです。
また、これらの対策は連鎖的に作用します。すでに実装されている一時的な適応策は、それぞれがスタック内の特定の地点で既知のクラッシュや誤った lowered 処理からモデルを守ります。その結果、実行がより深く進み、以前は隠れていた次の欠陥を露呈させることができます。つまり、各適応策は「回避策」であると同時に「探査手段」ともなります。既知の障害物を排除することで、モデル全体を十分に深く実行させ、その後に待ち構える問題を明らかにするのです。
アダプターには二つの重要な役割があります。一つは、Transformer モデルを Spyre 上で実行可能にする統合層としての機能です。もう一つは、複雑な実環境のアーキテクチャに対してプラットフォームを継続的に検証するツールとしての役割です。導入したすべてのモデルがテストケースとなり、そこで露見した不具合は、下位レイヤーの堅牢化に直接フィードバックされます。
適応事例
HF-adapters で実施している多様な適応手法の範囲を示すため、二つの具体例を解説し、その後、それらが共通する点と異なる点を振り返ります。
演算子の置換
最も小さなパッチは、現在サポートされていない演算子を、数学的に等価な別の演算子に置き換えるものです。
具体的な例として gelu
原文を表示
TL;DR
The AI model landscape never stops moving, and the software stack that runs those models is always a step behind: even on a mature compilation stack, a new model family often arrives with some novel module that doesn’t lower well, and on new hardware – where a young stack meets a whole ecosystem at once – the gap is far wider. Extending stack enablement to each new family has traditionally been slow, specialist work that delays deployment. In this blog we show how AI agents can facilitate day-one enablement for a new model or for entire ecosystems, by bridging between the model workflows and the compilation stack. We demonstrate this at the harder end of that spectrum: through a small number of AI-written adapters, we run stock HuggingFace Transformers models on IBM’s Spyre AI accelerator, achieving full enablement for thousands of models.
The problem: catching up to an evolving model landscape
The model landscape never stops moving. New architectures and checkpoints appear constantly — each a particular composition of operations, shapes, and numerical ranges — and the software that has to run them is always a step behind. Even on the most mature, widely-deployed stack, a brand-new model family lands with some novel module, some fused attention variant, some numeric range that the existing software doesn’t yet handle cleanly.
imageNew model families added to the HuggingFace Transformers library over time. Each step marks the inclusion of a prominent model family, illustrating the steady, accelerating pace at which new architectures arrive.
Running a model on any device requires a software stack – a compiler, a set of operator lowerings, and a runtime – that maps it onto the hardware’s cores, memory hierarchy, and number formats. That stack is a large, evolving piece of software, and a new architecture can exercise a corner of it that isn’t yet mature. Until that corner is filled in, the model cannot run, or doesn’t run well – and closing such a gap has traditionally taken weeks or months of specialist work.
New hardware is where the gap is at its widest. A new accelerator is not just a chip: it ships with a young stack still growing into the needs of different models. Here it is not one new model meeting a mature stack, but a whole ecosystem of models meeting a stack that is still being built – and that must simultaneously keep pace with new architectures landing on top of it. Enablement can’t wait for the stack to be complete; it should progress in parallel, letting real models run while the platform underneath them matures.
imageAI accelerator releases. Each dot marks the announcement date for a new chip. New hardware arrives almost as steadily as new models do – and every chip architecture needs a continually evolving software stack.
New hardware is the extreme case, but the challenge is a general one: keeping the software in step with the model landscape, whether the stack is mature or brand new. Below we describe a strategy for bridging that gap, and demonstrate it through a concrete instance – running stock HuggingFace Transformers models on IBM’s Spyre accelerator.
The strategy: adapters as a bridge between models and stack
The strategy we describe is a thin layer of runtime patches – adapters – that allow a stock model to run on a given platform today, without waiting for every underlying gap in the stack to be closed first. We assume that the platform already provides a PyTorch compiler that lowers
core tensor operations in ordinary torch code – including matrix multiplications, elementwise operations, and reductions – onto the target hardware, so most of the model logic runs through it unchanged. When some operation in a model doesn’t yet have a clean path through the stack, the adapter reaches in at runtime and swaps it for an equivalent one that does. The patches change how the model is expressed for the device, but not what it computes: the underlying math is preserved. An adapter isn’t a hand-optimized kernel – it hands the stack a form it can lower well, but performance remains the compiler’s responsibility.
Rather than blocking on the state of the stack, adapters provide a practical bridge across it as it stands today. A useful analogy is a large construction project. Around a building with active construction – whether it is still going up or already standing and being renovated — there is almost always scaffolding somewhere: temporary access ramps and support beams that keep work moving on whatever part isn’t finished yet. No single piece of scaffolding is permanent; each comes down once the structure behind it can stand on its own.
Adapters play the same role. An individual adapter is usually transitional: its job is to carry a model across one specific gap in the stack as it stands today, and it is designed to be removed once that gap is closed — as the platform matures, new optimizations are integrated, more architectures are enabled, and the permanent path opens up underneath it. Not every adapter comes down, though: some bridge a temporary gap the stack will eventually close, while others accommodate a genuine, lasting difference in the target hardware; and where an accelerator harware has a unique architecture, those bridges may stay in place for good.
The adapter layer, however, is permanent in a way no individual adapter is. Because the model landscape never stops moving, there is always some new gap the stack hasn’t caught up to yet — so even as old scaffolding comes down, new scaffolding goes up elsewhere. That layer connects two things evolving in parallel. On one side is a model ecosystem – in our case HuggingFace Transformers, thousands of models with a stable API and an enormous community. On the other is the platform’s hardware-lowering stack – in our case Spyre, a compiler and runtime stack that maps those models onto the accelerator device and is itself under continual development. The adapters sit in between, letting models run on the hardware while the two ends continue to evolve.
What makes this strategy practical at the scale of thousands of models is AI. Historically, enabling each new model family was a slow, specialist effort, requiring a great deal of work for every hardware platform and chip architecture. Coding agents change the economics, turning what used to be a bespoke effort into something that can keep pace with the ecosystem. The rest of this post shows how that plays out – but first we will introduce the concrete platform in which we implement this.
The platform: Spyre and torch-spyre
The hardware in our example is Spyre, IBM’s AI accelerator, built on the AIU (Artificial Intelligence Unit). It is made of small cores connected by a high-bandwidth ring, each with its own local scratchpad memory and arrays of processing elements that carry out the matrix multiplications at the heart of a model. A few things make it distinctive. First, it is dataflow-driven: computation is triggered by data arriving at a compute engine, which reduces the bottleneck of sequential control flow, and keeps the hardware busy on the structured, repetitive math that models are made of. This is in contrast to a conventional GPU, which executes kernels as explicit instruction streams across scheduled groups of threads. Second, Spyre uses reduced-precision number formats designed for inference, which lets it deliver high throughput at low power.
Spyre’s memory and compute operate on fixed-size chunks called sticks – 128 bytes, or 64 values in fp16 – and it expects tensor dimensions to line up on stick boundaries (see the Tiled Tensors RFC). This is a different contract than the one PyTorch and model code are written against, where a tensor is a flat array of any shape and the framework hides how it maps onto memory. Model architectures pick their head dimensions, sequence lengths, and vocabulary sizes for statistical and modeling reasons, with no notion of a stick – so in our scenario, part of an adapter’s job is reconciling those two views, by bridging between the HF Transformers model implementation and the Spyre compiler extensions in PyTorch.
The software stack that maps a model onto this hardware is torch-spyre, a PyTorch backend that compiles and runs ordinary torch code on Spyre: a model is compiled into a plan the hardware can execute. And the adapters – the temporary scaffolding from the previous section — are a project we call HF-adapters: runtime patches that let stock HuggingFace models run on Spyre today.
How AI helps build adapters
An adapter lives in the gap between two codebases. On one side is the model as Transformers expresses it – the modules, the attention blocks, the way a particular architecture wires its RoPE and its norms together. On the other is torch-spyre, the compiler and runtime that lower that computation onto the device. Writing an adapter requires understanding both at once and finding the exact places where they don’t yet meet: the operation the model expresses in a form the compiler can’t lower cleanly. In practice, this means following the model’s internal logic while tracing how each piece of it flows through the compilation stack. This is the part of the work AI has transformed.
Coding agents can now follow the internal logic of an entire transformer model at every level, from a single module up through the attention blocks to the full forward pass. They can trace the same computation down through torch-spyre’s lowering logic to see how it is meant to run on the hardware. Holding both views at the same time is what enables the core loop of this work: identify a gap in the stack, then draft a high-level patch that carries the model across it. The model side and the device side are usually documented in different places, in different languages, at different levels of abstraction. Reading both and cross-referencing them quickly is the bottleneck that once made an effort like this impractical to attempt at all.

A few things make this work in practice. We keep a knowledge base that describes both the hardware and the software stack as it evolves, so an agent can ground its reasoning in how Spyre actually behaves rather than in generic assumptions. We give it direct access to the source and GitHub of both the HuggingFace Transformers library and the torch-spyre backend, so it can trace the logic through the actual code, issues and pull requests. Moreover, frontier models already carry a deep working knowledge of machine learning and transformer architecture – they know what attention, RoPE, and RMSNorm are before they ever open our repository, which means the reading starts from understanding rather than from scratch.
Importantly, every adapter we add is also a record of which adaptations work, and for what reason. A new model is rarely a completely new problem: it is usually a variation on an architecture we have already brought up, and the closest existing adapter is both a template to imitate and a source of patches that can be reused directly. So each model we enable lowers the cost of the next one that resembles it, and adding a new adapter gets easier over time. The chart below shows this compounding in practice: a small number of distinct adapters, added over a few months, comes to cover the large majority of the models in the target set.
imageCoverage of the target model set from mid-April to late June 2026. The left axis counts embedding models, the right axis counts distinct adapters. By the final snapshot, 13 distinct adapters cover 7,960 of the 10,000 most-downloaded HF embedding models, of which 6,804 pass their end-to-end test on Spyre. The coverage lines rise in a few large steps rather than one model at a time: because most new models are variations on an architecture already brought up, each new adapter picks up a whole family of similar models at once. Effort scales with the number of architectures, the coverage it buys with the number of models. The gap between the two coverage lines — models that have an adapter versus models that pass on Spyre — illustrates the debugging challenge: an adapter is necessary but not sufficient, and closing that gap is where the human-in-the-loop diagnosis below is spent.
At the same time, human expertise and supervision remain essential. Two failure modes recur.
The first is that localization is genuinely difficult. When a model that is correct on CPU or GPU produces the wrong output on the device, narrowing down the exact source of the mislowering is rarely a matter of reading the code once. It means reproducing different parts of the model both in isolation and in concert — pulling a single block out to test it alone, then putting it back to see whether the failure survives the surrounding computation — because the fault often lives not in any one operation but in the interaction between them, where small faithful deviations line up in a way a downstream component happens to amplify. When the original and adapted code run on the same CPU or GPU, we generally expect bitwise-identical outputs, confirming that the adapter preserves the computation. However, this bitwise determinism expectation does not extend to the target hardware, where expected numerical drift can be difficult to distinguish from a genuine lowering error. Localization is made harder still by the fact that the compiler does not lower each operation in isolation: it fuses neighboring operations together, and which operations get fused depends on the context they appear in. The same operation can lower one way when it stands alone and a different way once it is fused with what surrounds it — so an operation that tests as faithful when pulled out can still misbehave in place, precisely because pulling it out changed the fusion. This is patient, method-driven work, and no single automated probe substitutes for it.
The second is that the agent will often draw the wrong conclusion from a targeted experiment. A large numerical discrepancy somewhere deep inside the model is a clue, not a verdict. It is easy — for a person and an agent alike — to find an alarming difference in some intermediate tensor and conclude that it is the cause of the end-to-end failure. But downstream layers routinely attenuate an internal error until it never reaches the output, so a component can look badly broken and be entirely harmless to the final result. The discipline that separates a real diagnosis from a plausible one — trace the discrepancy forward to the actual output, distrust any probe that disagrees with the end-to-end result, confirm that the one thing you changed is really the thing that mattered — is judgment an agent does not reliably supply on its own. It will propose a confident explanation from a single suggestive experiment, and someone has to check whether it holds up.
The division of labor follows from this. AI handles the wide, repetitive, cross-referencing part of the work: reading two large codebases at once, recognizing an architecture, and drafting a first adapter by analogy to the ones that came before. Human expertise handles the diagnosis: localizing the silent failures that only appear on the device, and not trusting a lead until it has survived the end-to-end test. Another important role for the human is deciding what the agent should learn from past mistakes — updating the procedures it follows when drafting adapters and debugging, and separating isolated issues from recurring “gotchas” that are worth capturing. These are recorded as agent skills and memories that make the process more efficient, but do not remove the need for explicit human supervision.
Adapters as a validation tool
Each adapter does more than carry its model onto the device. In doing so, it also exposes exactly where the stack underneath still needs work.
This is a general property of bridging a mature ecosystem to a young stack. The gaps in such a stack rarely live in a single operation; they live in combinations no unit test anticipated, and the only reliable way to surface them is to run real workflows end to end against a trusted reference. Adapters make that possible before the stack is finished – so every model they carry doubles as a stress test of the platform.
In our example, the Torch-Spyre team works primarily at the lower levels of the software stack – the compiler, the operator lowerings, the runtime that places work on the device. At that level it is genuinely hard to predict how a real model will behave. A production model is a particular composition of shapes, operators, weight layouts, and numerical ranges, and it is often that specific combination – not any one piece in isolation – that trips over a gap in the stack. The gaps are real, but from the bottom of the stack they are mostly invisible: nothing about a single lowering tells you which model, at which layer, with which input, will finally exercise it.
Running stock HuggingFace models end-to-end is what makes these gaps visible. An end-to-end divergence from a CPU/GPU reference is a strong signal that something in the platform needs attention. In practice the issues that surface fall into a few recurring families:
Missing lowering paths – a block or fused shape the stack cannot yet lower, even when the individual ops are already working in isolation.
Device-only numerical behavior – values that overflow or turn into NaNs on the device where the CPU/GPU reference stays finite.
Alignment and padding assumptions – shapes that quietly corrupt results when they don’t match what the hardware expects.
What ties these together is that they are largely fusion-dependent. When a full model is compiled, the stack fuses different ops and shapes into combined kernels, and which things get fused depends on the surrounding graph. That is why an operator can pass low-level testing on its own and still fail here: the failure belongs to the fused context, not the bare op.
Real models also bring real data. Low-level tests typically feed operators random tensors, but trained weights and the activations they produce have structure that random inputs don’t — particular value ranges, near-constant rows, occasional large outliers. That structure is often exactly what pushes a kernel into overflow or a NaN. So none of these families are apparent from a unit test of an operator alone; they emerge only when a full model drives real weights and activations through the stack.
This also builds on itself. The temporary adaptations already in place each get a model past a known crash or mislowering at one point in the stack. Doing so is what lets execution reach further in and expose the next gap, which was invisible while the model was still failing earlier. So each adaptation is both a workaround and a probe: by clearing a known obstacle, it lets the full model run deep enough to reveal whatever comes after it.
So the adapters play a double role – they are an integration layer that lets Transformer models run on Spyre today, and they are a validation tool that continuously exercises the platform against the messiness of real architectures. Every model we bring up is also a test case, and the failures it exposes feed directly back into hardening the lower layers.
Adaptation examples
To illustrate the range of adaptations we implement in HF-adapters, we’ll walk through two examples, and then step back to see what they have in common, and where they differ.
Replacing an operator
The smallest patches replace one currently unsupported operation with a mathematically identical one.
A concrete example is the gelu
関連記事
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み