HN 日本語サマリー

← 一覧へ戻る
AI・機械学習

エージェントにコードを速くさせることで、高速なRustコードを書く

Writing Rust code that's fast by asking agents to make the code faster (minimaxir.com)

84 pointsby mooreds46 コメント

要約

本記事では、エージェント型LLM(大規模言語モデル)が、指示を繰り返し与えることでRustコードを著しく高速化できることを実証しています。特に、UMAPアルゴリズムの実装において、線形代数ライブラリの活用やSIMD命令の積極的な利用などにより、2倍から20倍の速度向上を達成しました。この手法は、PythonとRustの連携によるパフォーマンス向上にも応用可能です。

全文翻訳

2025年1月、LLMに「コードをより良く書く」と繰り返し指示することで、より良いコードを書けるようになるのではないかという仮説を立て、ブログ記事にしようと考えていました。これは、堅牢なエージェント型コーディングが登場する前のことでしたが、Claude Sonnet 3.5はアルゴリズム的なPythonコードを繰り返し改善することができました。「より良く」という指示は曖昧すぎたため、Sonnetはその曖昧さを悪用して、無数の不要な機能を追加しましたが、コードは確かに高速になりました。一般的なコーディングの問題を解決するために特別にRLHF(人間からのフィードバックによる強化学習)されたエージェント型LLMが登場した現在でも、最適化は一般的にそのスイートに含まれていません。 そのブログ記事の最後に、LLMがRustコードを書き、PyO3を使用して言語をブリッジすることで、Pythonの使いやすさとRustの速度を得るという、スーパーファストなPythonコードを書けるようになるという仮説について述べました。その記事の初期ドラフトでは、同じ「コードをより良く書く」という指示をベースとなるRustコードに適用することで、その速度を劇的に向上させ、それがPythonコードにも波及するという主張がなされていました。しかし、当時はRustについて十分な知識がなく、そのような主張をするには証拠なしではあまりにも大胆すぎました。 Opus 4.5のリリースによりエージェント型コーディングがより現実的になって以来、数ヶ月にわたるテストと実験を経て、適切なガードレールと制約を与えられれば、最新のエージェント型LLMは現在の最先端アプローチよりも大幅に高速なRustコードを書くことができると自信を持って確認できます。さらに、Opus 4.5以降の各フロンティアモデルのリリースでLLMのコーディング能力が劇的に向上するにつれて、最適化はさらに改善され、ドメインによっては累積で2倍から20倍の速度向上が得られています。 さらに重要なのは、この記事は曖昧な話ではなく、使用したプロンプトとベンチマーク結果の両方を含んでいることです。警告しておきます。 反復的な「ベンチマックス」 当初、ソフトウェアを高速化することは、これらの新しいエージェント型モデルをテストおよび比較するための良い定量的方法でした。Pythonとの連携と速度の理由から、主にRustをターゲット言語として使用しましたが、高速な実装が発見された場合に特に役立つRust言語の他の側面もあります。例えば、メモリ安全性や、WebAssembly/WASMにコンパイルして、あまり手間をかけずにWebブラウザで実行できることです。しかし、技術的には最も高速なコードにならない可能性がある重要な制約として、可能な限りunsafeコードの使用を禁止します。 最初のテストケースは、機械学習アルゴリズムをRustで再実装することでした。これにより、データサイエンティストとしての生産性が大幅に向上する可能性があります。当時、10年以上かけて改良され、すでにCで書かれている、戦術的にテストされたアルゴリズムに勝てると仮定するのは傲慢でした。そのため、Rustの低レベルの利点はそれほど顕著ではありませんでした。最も最適化したいアルゴリズムはUMAPでした。これは次元削減に有用なアルゴリズムで、私の仕事で使っていましたが、ビッグデータへのスケーリングが悪く、非常に遅いため、cuMLのような代替手段はセットアップに時間がかかります。UMAPのRustクレート(例: umap-rs)はすでに存在しており、それをフォークしてClaude Opus 4.5にPython/PyO3サポートを追加するようにプロンプトできますが、実験と学習体験として、最適化を可能な限り低レベルで行うために、最小限のRust依存関係でエージェントにアルゴリズムをゼロから書かせたいと思いました。 Rustには、criterionクレートという包括的なベンチマークツールがあり、すべてのエージェントがその活用方法を知っています。criterionはベンチマークを実行し、イテレーションの結果を追跡してパフォーマンスが改善または後退したかを確認し、その変更が統計的に有意であるか、単なるノイズであるかを計算できます。 典型的なcriterionの出力。前の実行と比較して3.5倍の速度向上が示されています。 まず、UMAPのRustクレートを作成するための最初のプロンプトで、Opus 4.5に異なる入力データサイズのベンチマークを作成するように依頼しました。なぜなら、小規模データセットの最適化は大規模データセットでは機能しない場合があり、その逆もまた然りだからです。 その後、ベンチマークスイートを作成して実行し、結果をMarkdownファイルとして保存してください。ベンチマークスイートには、最大100000x768の入力を含め、CPUモードとGPUモードの両方でテストする必要があります。 このアプローチにより、criterionを使用したベンチマークが作成され、線形代数を高速化するためにfaerを使用したり、SIMD操作を高速化するためにsimsimdを使用したりするパフォーマンス機能の改善をプロンプトした後、手動でベンチマークスイートを再実行しました。これはすぐに手間のかかる作業になりました。なぜなら、速度の後退がないことを確認するために、変更ごとに各ベンチマークを手動で再実行する必要があったからです。 プロンプトスタイルのサイドノート エージェント型LLMへのプロンプト方法は珍しいです。通常、Markdownドキュメントで事前に書かれた非常に長いプロンプトを提供し、強調のためにALL CAPSと**太字**を使用します。これは、プロンプトエンジニアリングの使用を通じて、このブログ記事で詳述されている他の多くのトリックとともに、すべてのニュアンスを捉えるためです。プロンプトエンジニアリングは、最新のモデルが曖昧さを正しく処理するのに十分賢くなったため、死んだと主張する人もいるかもしれませんが、私は強く反対します。なぜなら、LLMはこれらのニュアンスをうまく処理するようにもはるかに改善されているからです。 Zed Agentを使用し、ファイル(左)をタグ付けしてMarkdownドキュメント(右)からプロンプトを実行します。 エージェントが誤ってリポジトリをrm -rfしないという十分な自信を得た後、エージェントを自律的に実行させ、速度の増加が達成されるまでイテレーションする許可を与え、うまくいけば、という実験を行いました。 **ベンチマーク結果が改善しなくなり、クレートが可能な限り高速になるまで、最適化を繰り返し、問題を解決し続けてください**。アイデアが尽きるまでイテレーションを続ける許可があります。 「可能な限り高速」というのは曖昧すぎることが判明し、Opus 4.5は怠惰だったので、実際の速度向上はほとんどなく、いくつかのハイパーパラメータを微調整して終了しました。必要なのは、合格/不合格できる明確な目標でした。そのため、プロンプトを洗練させました。 まず、**これ以上の変更を加えることなく**、CPU Rustベンチマークを実行して、真のパフォーマンスベースラインを確立してください。次に、クレートコードを最適化して、すべてのCPUベンチマークが真のパフォーマンスベースラインよりも**少なくとも1.2倍高速**に実行されるようにしてください。理想的には可能な限り高速にしてください。この実行時間の短縮を達成するために、ベンチマークをハックしないでください。ライブラリコードでイテレーションするだけです。`unsafe`コードを追加する以外は、どのような手法(例: 新しいクレートのインポート)を使用しても構いません。**ベンチマークパフォーマンスが収束し、最適化のアイデアが尽きるまで、このプロセスを繰り返してください**。イテレーションを続ける許可があります。各ベンチマークイテレーションの後、コンソールに真のパフォーマンスベースラインに対する相対結果を報告してください。イテレーションで迅速かつ高影響の成果を優先し、それに応じて変更を加えてください。必要な変更について考えすぎないでください。 これは非常にうまく機能し、ベンチマークで1.2倍の速度向上が得られただけでなく、エージェントはメトリック制約に達した後も継続し、メトリック制約が実行不可能であった場合にのみ停止しました。この場合、エージェントは1.5倍から2.0倍の速度向上を達成しました。低レベルのRust最適化は、SIMD操作のより積極的な活用、関数の融合、ループのアンローリング、中間キャッシュの作成、借用ではなくArcの使用(可能な限り)、および入力データに基づいたパフォーマンスプロファイルの作成(例: データが小さい場合は、オーバーヘッドがメリットを消去するため、rayonデータ並列処理を使用しない)など、多くの技術を中心に展開されました。 「1.2倍高速」を健全性テストとして選択しました。目標が高すぎると、エージェントは危険または冗長な書き換えによってそれを達成するために不正行為をする可能性があります。エージェントが速度向上/後退の原因をより簡単に特定できるため、小さな変更の方が優れています。したがって、イテレーションに関する注意書きを参照してください。GPT-5.3 CodexやOpus 4.6のような新しいフロンティアLLMがリリースされた後、このプロンプトを新しいLLMごとに変更せずに繰り返し実行したところ、それぞれが以前のパスよりも累積で1.5倍から2.0倍の速度向上を達成することができました。数ヶ月かけてGPT-6 Astraまで進むと、約7.5倍から32倍の速度向上になります。