Mojo入門

Mojo

こちらの記事の翻訳になります:

Modular Docs - Why Mojo🔥
A backstory and rationale for why we created the Mojo language.

Why Mojo

私たちがModularを始めたとき、新しいプログラミング言語を作る意図はありませんでした。しかし、世界のML/AIインフラを統一することを目的としてプラットフォームを構築しているうちに、スタック全体でのプログラミングが複雑すぎることに気付きました。さらに、手作業で多くのMLIRを書いていて、楽しいものではありませんでした。

私たちが求めていたのは、マシン学習で普及しているアクセラレータやその他の異種システムを対象とすることができる革新的でスケーラブルなプログラミングモデルでした。これは、強力なコンパイル時のメタプログラミング、適応的なコンパイル手法の統合、コンパイルフロー全体でのキャッシュ、そして既存の言語ではサポートされていないその他の機能を持つプログラミング言語を意味していました。

アクセラレータは重要ですが、最も一般的で、時には見過ごされがちな「アクセラレータ」の1つはホストCPUです。現在、CPUには多くのテンソルコアのようなアクセラレータブロックやその他のAI加速ユニットがありますが、特定のアクセラレータが対応していない操作(データのロード、前処理・後処理、外部システムとの統合など)の「フォールバック」も担っています。従って、特定のプロセッサでしか動かない「アクセラレータ言語」でAIを向上させることはできないことが明らかでした。

適用型AIシステムはこれらの問題すべてに対処する必要があり、私たちは1つの言語だけでそれを実現できる理由がないと判断しました。そこでMojoが誕生しました。

Mojoの使命には、コンパイラ内部の革新や現行および新興アクセラレータのサポートを含めることにしましたが、言語構文やコミュニティで革新する必要はないと考えました。そこで、非常に広く使われており、AIエコシステムに愛されている上、非常に素晴らしいPythonエコシステムを取り入れること

に決めました。

Pythonエコシステムを採用することで、Mojoはすでに確立されている言語とコミュニティの利点を享受できるようになりました。私たちは、Mojoを開発することで、コンパイラ技術とアクセラレータのサポートを向上させ、統一されたプログラミングモデルを提供することができると信じています。その結果、AI/ML開発者が効率的かつスケーラブルな方法で、さまざまなハードウェアやシステムに対応することが可能になります。

Pythonの人気と、AIコミュニティにおけるその地位を利用して、Mojoは新しい革新的なプログラミング言語として急速に成長し、AI/ML分野において重要な役割を果たすことが期待されています。私たちがMojoで提供しようとしている機能は、AI技術の発展と広範なアプリケーションへの適用を加速させ、この分野に革新をもたらすことができるでしょう。

Mojo as a member of the Python family

Mojo言語は高い目標を持っています。Pythonエコシステムとの完全な互換性を実現し、予測可能なローレベルのパフォーマンスと制御を実現し、コードのサブセットをアクセラレータにデプロイできる機能が必要です。また、エコシステムの分断も望んでいません。私たちは、時間とともに人々が私たちの仕事を有益だと感じることを望んでおり、Python 2からPython 3への移行のようなことが再び起こらないことを望んでいます。これらは決して小さな目標ではありません!

幸いなことに、Mojoは新しいコードベースでありながら、概念的にはゼロから始めているわけではありません。Pythonを受け入れることで、デザイン努力が大幅に簡素化され、ほとんどの構文がすでに指定されているためです。代わりに、コンパイルモデルの構築や特定のシステムプログラミング機能の設計に努力を集中することができます。また、他の言語(例えば、Clang、Rust、Swift、Julia、Zig、Nimなど)での膨大な作業や、MLIRコンパイラエコシステムを利用することで恩恵を受けます。さらに、大規模なObjective-Cコミュニティのほとんどを新しい言語に移行させたSwiftプログラミング言語の経験も活用できます。

さらに、Mojoにとって長期的な目標は、Pythonのスーパーセットを提供し(つまり、既存のプログラムと互換性を持つ)、CPythonをすぐにロングテールエコシステムの有効化に活用することだと判断しました。Pythonプログラマにとって、Mojoはすぐに馴染みのあるものであることを期待し、希望していますが、同時に、PythonがCやC++にフォールバックすることを可能にするシステムレベルのコード開発の新しいツールも提供します。私たちは、世界に「静的は良い」や「動的は良い」と言いたいわけではありません。どちらも適切なアプリケーションで使用すると良いと考えており、言語がプログラマが判断を下せるようにすべきだと信じています。

Mojoは、既存のPythonプログラムと互換性を持ちつつ、新たなシステムレベルのコード開発ツールを提供することで、プログラマが柔軟に開発できるようになることを目指しています。そして、Mojoは、静的と動的のどちらの特性も適切に活用することで、さまざまなアプリケーションに対応できる言語となることが期待されます。

Pythonプログラマにとって、Mojoは新たな可能性を提供する言語となるでしょう。Mojoの採用によって、開発者は、これまでPythonがCやC++に依存していた領域でさえも、効果的に開発できるようになります。言語が革新的であることは重要ですが、最も重要なのは、それがどのように開発者に役立つかということです。そして、Mojoはまさにそのような言語であることを目指しています。

How compatible is Mojo with Python really?

Mojoは、Pythonの多くの基本機能(async/await、エラー処理、可変長引数など)をすでにサポートしていますが、まだ非常に初期の段階であり、多くの機能が欠けているため、現時点では互換性は低いです。Mojoはまだクラスすらサポートしていません!

とはいえ、私たちは2つの大きく異なる互換性の道のりを経験しています。まず、「Clang」コンパイラは、LLVMの一部であり、C、C++、Objective-C(そしてCUDA、OpenCLなど)を対象としたものです。Clangの主要な目標は、GCC、MSVCなどの既存のコンパイラに対する「互換性のある代替品」であることでした。直接的な比較は難しいですが、Clangの問題の複雑さは、Pythonの互換性のある代替品を実装することの複雑さよりも1桁大きいと考えられます。この経験から、Pythonコミュニティに対してこれを適切に実現できる自信が得られます。

もう1つの例は、Swiftプログラミング言語で、Objective-Cのランタイムと言語エコシステムを受け入れ、何百万人ものプログラマ(および膨大な量のコード)を段階的に全く異なるプログラミング言語に移行させました。Swiftでは、「ランタイム互換性」を持つ方法や、既存のランタイムと協力する方法について学びました。PythonとMojoの場合、MojoはCPythonランタイムと直接協力し、CPythonクラスとオブジェクトとの統合に同様のサポートを提供することが期待されています。コード自体をコンパイルすることなく、既存のコードの大規模なエコシステムとやりとりできるようになりますが、移行に関する段階的な作業を行うことで、段階的な利益が得られる移行アプローチが提供されます。

全体として、互換性を最優先にした目標設定、デザインに対する継続的な注意、そして完全な互換性に向けた段階的な取り組みが、私たちが目指すところに到達するための道しるべとなると考えています。

Intentional differences from Python

互換性と移行性は成功のカギですが、Mojo自体も第一級の言語として機能させ、新しいキーワードを導入したり文法の制約を加えたりできない状況に陥れるわけにはいきません。そのため、私たちの互換性に対するアプローチは以下の2つです。

1つ目は、既存のPython3コードをすべて「そのまま」CPythonで実行し、そのランタイムを変更せずに利用することで、エコシステム全体との完全な互換性を実現します。この方法でコードを実行すると、Mojoの利点は得られませんが、既存のエコシステムが存在し利用可能であること自体が、Mojoの開発を加速させ、Pythonがすでに高レベルのプログラミングに適していることを活用できます。

2つ目は、PythonコードをMojoに移行したい人のために、非常に高い互換性を提供する機械的な移行ツールを提供します。例えば、Mojoはバックティック機能を提供し、あらゆるキーワードを識別子として使用できるようにすることで、これらのキーワードを識別子やキーワード引数として使用するコードに対して、容易な機械的な移行経路を提供します。Mojoに移行したコードは、高度なシステムプログラミング機能を利用できるようになります。

これにより、Mojoは主にCPythonベースの環境にうまく統合されると同時に、Mojoプログラマがコード(1つのモジュールやファイルごと)を徐々にMojoに移行できるようになります。このアプローチは、AppleがObjective-CからSwiftへの移行で実証されたものです。SwiftコードはObjective-Cクラスをサブクラス化して利用でき、プログラマはアプリケーションでSwiftを段階的に採用できました。また、SwiftはObjective-Cプログラマ向けの便利なAPIを構築するのにも適しており、MojoもCPython向けのAPIを実装するのに最適な方法になると期待されます。

Mojoと移行サポートの構築には時間がかかりますが、私たちはこれによってエネルギーを集中させ、分散させずに済むと自信を持っています。また、CPythonとの関係は両方向から構築できると考えています。CPythonチームが最終的にインタプリタをCではなくMojoで再実装することになったら、それは素晴らしいことではないでしょうか?

Detailed motivation

Mojoは、機械学習において普及しているアクセラレーターやその他の異種システムに革新的なプログラミングモデルをもたらすことを目標に開始しました。しかし、最も重要であり、普及している「アクセラレーター」の中で実際には、ホストCPUがその1つです。これらのCPUは、テンソルコアのようなアクセラレーターブロックや専用のAI加速ユニットがたくさん搭載されていますが、アクセラレーターがサポートしない操作を「フォールバック」としてサポートするという重要な役割も担っています。これには、データの読み込みや前処理・後処理、C++などで記述された外部システムとの統合などが含まれます。

そのため、問題の狭い範囲(例えば、テンソルだけを対象とした)限定的なアクセラレータ言語を構築することはできませんでした。私たちは、汎用プログラミングの全ての範囲をサポートする必要がありました。同時に、構文やコミュニティにおいて革新する必要性は見いだせず、そこでPythonエコシステムを受け入れて完成させることにしました。

Why Python?

Pythonは、機械学習分野だけでなく、無数の他の分野でも主要な存在です。学習が容易で、重要なプログラマー層(例えばデータサイエンティスト)に知られており、素晴らしいコミュニティがあり、多くの価値あるパッケージがあり、幅広い優れたツールが揃っています。Pythonは動的プログラミング機能を通じて美しく表現力豊かなAPIの開発をサポートし、TensorFlowやPyTorchのような機械学習フレームワークがC++で実装された高性能ランタイムのフロントエンドとしてPythonを採用しています。

現在のModularでは、Pythonはお客様から要求されるAPIスタックの一部であり、これは譲れない部分です。スタック内の他のすべてが交渉可能であることを考慮すると、「Pythonファースト」のアプローチから始めるのが理にかなっています。

さらに主観的に言えば、Pythonは美しい言語であり、シンプルで組み合わせ可能な抽象化が設計されており、実際のインデントと冗長な句読点を省略し、Modularに必要な強力な(動的)メタプログラミング機能を持っています。Pythonエコシステムの人々が、私たちの新しい方向性をPythonと競合しようとするのではなく、次のレベルへと進めるととらえてくれることを願っています。

What’s wrong with Python?

Pythonはよく知られた問題を抱えています。最も明らかなのは、低レベルでの性能が低いことや、GILのようなCPythonの実装上の問題です。これらの課題を改善するための多くのプロジェクトが進行中ですが、Pythonによって引き起こされる問題は、より深刻であり、特にAI分野に影響を与えています。ここでは、技術的な制約について語るのではなく、2023年現在のこれらの制約による影響について語ります。

このセクションでPythonに言及しているのは、すべてCPython実装を指しています。他の実装については後ほど説明します。

The two-world problem

さまざまな理由から、Pythonはシステムプログラミングに適していません。幸いなことに、Pythonは優れた接着剤の役割を果たし、CやC++への低レベルなバインディングにより、より良いパフォーマンス特性を持つ他の言語でライブラリを構築することができます。これにより、numpy、TensorFlow、PyTorchなどの数多くのライブラリが実現されました。

しかし、このアプローチはPythonライブラリの高性能化に効果的ですが、コストがかかります。ハイブリッドなライブラリを構築することは非常に複雑で、CPythonの内部構造を低レベルで理解する必要があり、C/C++/…プログラミングの知識が必要であり、Pythonを最初に使う目的を損なってしまいます。また、大規模なフレームワークの進化を難しくし、(機械学習の場合)「グラフベース」のプログラミングモデルを推進し、これは「eagerモード」のシステムよりも基本的な使い勝手が悪くなります。TensorFlowがその典型であり、PyTorch 2の多くの取り組みは、より積極的なコンパイル方法を実現するためにグラフを発見することに焦点を当てています。

システム複雑性の面での2つの世界問題の根本的な性質を超えて、エコシステム全体でさらに複雑な状況が生じています。デバッガは通常、PythonとCのコードをまたいでステップ実行できず、できるものも広く受け入れられていません。パッケージエコシステムにとっても、C/C++コードと一緒に扱うのは煩わしい問題です。PyTorchのようなC++に大きな投資があるプロジェクトは、意図的にPythonへのコード移行を進めているのは、使い勝手が向上することを知っているからです。

The three-world and N-world problem

Pythonエコシステム全体で2つの世界の問題が一般的に感じられていますが、機械学習フレームワークの開発者にとってはさらに悪化しています。AIは加速器に大きく依存しており、それらの加速器はCUDAのような独自のプログラミング言語を使用しています。CUDAはC++の派生でありますが、独自の特別な問題と制約があり、デバッガーやプロファイラーなどの一貫したツールがありません。また、実質的に1つのハードウェアメーカーにロックされています!

AI業界では、ハードウェアのイノベーションが驚異的な勢いで進んでおり、その結果、複雑さが制御不能になっています。現在、加速器向けの限定的なプログラミングシステム(OpenCL、Sycl、OneAPIなど)を構築しようとする試みが多数存在しています。この複雑さの爆発は、引き続き増加し続けており、これらのシステムのいずれも、業界に深刻な悪影響を与えるツールやエコシステムの基本的な分断を解決していません。

Mobile and server deployment

Pythonエコシステムのもう一つの課題はデプロイメントです。これには、依存関係を厳密に管理したい人や、密封されたコンパイルされた「a.out」ファイルをデプロイできることを好む人、マルチスレッドやパフォーマンスが非常に重要な人など、さまざまな側面があります。これらの分野でPythonエコシステムが前進することを私たちは望んでいます。

Related work: other approaches to improve Python

Pythonを改善するための他のアプローチ Pythonを改善するための多くのアプローチがあります。最近の作業では、Pythonを高速化し、GILを置き換えること、Pythonのように見えるがそれらのサブセットである言語、Pythonと統合されているが一級言語ではない組み込みDSLなどがあります。すべての取り組みを網羅的にリストアップすることはできませんが、これらの分野のいくつかの課題と、それらがModularの使用に適していない理由について説明できます。

Improving CPython and JIT compiling Python

最近、CPythonのパフォーマンスやその他の実装問題の改善に多くのエネルギーが注がれており、これによってコミュニティに大きな成果がもたらされています。この取り組みは、現行のCPython実装を段階的に改善するために素晴らしいものです。Python 3.11は、内部の改善によってPython 3.10よりも10-60%高速化が図られ、Python 3.12はトレース最適化を用いてさらに進むことを目指しています。GILを制御しようとする他の多くのプロジェクトや、PyPy(他にも多数)のようなプロジェクトがJITコンパイルやトレーシングアプローチを使ってPythonを高速化しています。

これらは素晴らしい取り組みですが、統一された言語を加速器に移すために役立ちません。最近の多くの加速器は、非常に限られた動的機能しかサポートしていないか、それを非常に低いパフォーマンスでしかサポートしていません。さらに、システムプログラマは、「パフォーマンス」だけでなく、計算方法についての「予測可能性と制御」を求めています。

これらのアプローチに私たちは賛成ですし、コミュニティにとって価値があると興奮していますが、残念ながら私たちのニーズを満たしていません。Pythonライブラリ内でCやC++を使用する必要を排除したい、最高のパフォーマンスを求めており、場合によっては動的機能を一切受け入れられないため、これらのアプローチは役に立ちません。

Python subsets and other Python-like languages

「デプロイ可能な」Pythonを構築しようとする試みが多くありますが、PyTorchプロジェクトのTorchScriptが一例です。これらは、低依存性のデプロイメントソリューションを提供し、高性能であることがあるため、有用です。Pythonに似た構文を使用するため、新しい言語よりも学びやすいことがあります。

一方で、これらの言語は広く採用されていません。サブセットであるため、一般的にはPythonエコシステムと相互運用できず、優れたツール(デバッガーなど)がなく、Pythonで互換性が損なわれるような変更を一方的に行うことがあります。たとえば、これらの言語の多くは、単純な整数の動作を変更して、Pythonと互換性のある数学を生成するのではなく、ラップします。

これらのアプローチの課題は、Pythonの弱点を解決しようとするものの、Pythonの強みを活かすのに十分でないということです。最善の場合、これらはCやC++の新たな代替手段を提供できますが、Pythonの動的なユースケースを解決せず、「二つの世界の問題」を解決できません。このアプローチは破片化を招き、非互換性が移行を困難に、あるいは不可能にしてしまいます。Python 2からPython 3への移行がどれだけ困難であったかを思い出してください。

Embedded DSLs in Python

もう一つの一般的なアプローチは、Pythonのデコレータを使ってPythonに組み込まれたDSLを構築することです。この例には、TensorFlowの@tf.functionデコレータやOpenAIのTritonプログラミングモデルの@triton.jitなどがあります。これらのシステムの大きな利点は、Pythonエコシステムのツールとすべて互換性があり、Pythonのロジックにネイティブに統合されるため、埋め込まれたミニ言語が動的ユースケースにおいてPythonの強みと共存できることです。

しかし、これらのシステムによって提供される埋め込みのミニ言語は、驚くべき制限があり、デバッガーや他のワークフローツールとうまく統合されず、私たちが求めるような異質な計算を統一する言語としてのネイティブ言語統合レベルをサポートしていません。私たちは、全体のシステムの使いやすさを向上させ、もっと一貫性を持たせることで、シンプルさを向上させることを望んでいます。埋め込みDSLはデモをすばやく実行できる手段ではありますが、私たちのユースケースに対してより良い使いやすさと予測可能性を提供するために、追加の努力と作業を行うことになっています。

コメント

タイトルとURLをコピーしました