Activity, over time
Daily observations from the public event archive.
Attention
Daily stars & forks
Star accumulation
Cumulative stars
Pull requests
Daily opens & merges
Conversations
Daily issues & comments
Community
Daily accounts & reviews
Releases
Daily releases
Trending history
Daily top 10 · last 90 days · UTC
Mentions
Stars
Forks
Contributors
Latest stargazers
The last 10 distinct accounts we observed this year.
Most active participants
PR, issue, comment & review events in the past year.
Packages
Scan pending.
Live mentions badge
Show how many posts mention your project in the last 30 days.
Live mentions · last 30 days
Mentions
SkyPilot v0.14.0 の解説 はじめに クラウドの VM、Kubernetes、Slurm のどれにでも同じ書き方でジョブを投げる道具 SkyPilot の v0.14.0 が、2026 年 10 月 6 日に出ました。この記事では、SkyPilot が何をする道具かを押さえたうえで、v0.14.0 の機能と性能に関わる変更を整理します。 v0.14.0 の項目 何が変わったか 実務での意味 動的なジョブグループ 動いているグループの中から投げたジョブも、グループの一部になる 学習の途中で投げた評価のジョブも、グループを取り消すと一緒に止まる AWS Neuron への対応 Kubernetes の上の Trainium のノードに、ジョブを置けるようになった Trainium のノードを、GPU と同じ --gpus の書き方で頼める EFA の改善 AWS の高速なノード間通信 EFA の数を、ノードの自動増減を SkyPilot に知らせたクラスタでは、アクセラレータのノードがまだ 0 台でも見積もれ、複数ノードの Pod が 1 つの AZ にまとまる 複数ノードの学習が、気づかないまま遅い TCP の通信で動いたり、通信を始められなかったりすることが減る Kueue との連携の改善 Kubernetes の待ち行列 Kueue で待っている時間を、確保の時間に数えなくなった 待ち行列が混んでいるだけのジョブが、短く設定した確保のタイムアウトで打ち切られない 複数ユーザーでの実行 Slurm に、依頼した人それぞれの Unix アカウントでジョブを出せる Slurm 側で設定した利用量の記録や公平な割り当てを、人ごとに効かせられる コンテナクラスタの停止と再開 Slurm の上のコンテナのクラスタを止めて、あとで再開できる ノードを手放しても、入れたパッケージやファイルを残したまま再開できる SkyPilot とは何か 1 つの書き方で複数の基盤に投げる SkyPilot は、Kubernetes、Slurm、クラウドの VM のどれに対しても、同じ 1 つのタスクの書き方で、計算資源の確保からジョブの実行と後片付けまでを受け持つ道具です。基盤ごとにジョブの書き方も、空きの探し方も、止まったときの立て直し方も違うので、その違いを SkyPilot が引き受けます。 組織で複数のプロジェクトを進めていると、複数のクラウド、複数の Kubernetes や Slurm のクラスタ、複数のリージョンを併用することがあります。こうしたクラスタは、それぞれ別々に構築して立ち上げます。SkyPilot は、こうして別々に立てたクラスタやクラウドの VM に、統一的にジョブを投げるための道具だと理解すればよいです。クラウドの VM の場合は、SkyPilot がインスタンスを自分で作ります。 タスクは、必要な資源、準備のコマンド、実行のコマンドを YAML に書いたものです。 resources: accelerators: H100:8 workdir: . setup: pip install -r requirements.txt run: python train.py これを requirements.txt と train.py のあるディレクトリに task.yaml として保存し、sky launch task.yaml を実行すると、SkyPilot は条件を満たす基盤と場所を探して計算資源を確保します。確保に失敗したら、別の場所でやり直します。README のとおり、計算資源はすべて利用者自身のクラウドのアカウントやクラスタの中に作られます。 sky launch は対話的に使う開発用のクラスタを、sky serve は推論のエンドポイントを作ります。sky jobs launch で投げたマネージドジョブは、スポットインスタンスの回収やノードの故障が起きると、資源を確保し直して実行し直します。途中から続けるには、アプリケーションがチェックポイントを保存して読み込む必要があります。sky コマンドは SkyPilot の API サーバーに依頼を送ります。1 人で使うときは手元に API サーバーが自動で立ち、チームで使うときはリモートに 1 つ立てて共有します。 AWS では、SageMaker HyperPod(AWS が管理する学習用のクラスタで、EKS 版と Slurm 版がある)、Amazon EKS、Slurm を使う AWS Parallel Computing Service(AWS PCS)などを構築するリファレンスのテンプレートが awsome-distributed-ai にあります。SkyPilot のドキュメントは、EFA を使える投げる先として、HyperPod の EKS のクラスタと Slurm のクラスタを挙げています。awsome-distributed-ai の NVIDIA NeMo 2.0 の学習の例でも、NeMo の学習を Python の設定から投げる NeMo-Run が、Amazon EKS と SageMaker HyperPod EKS にジョブを出す役として SkyPilot を使います。SkyPilot は、カリフォルニア大学バークレー校の研究室から生まれたオープンソースのソフトウェアで、ライセンスは Apache 2.0 です。 Kubernetes や Slurm との関係 SkyPilot は、どのクラスタにジョブを出すかを選び、そのクラスタが受け付ける形に直して渡します。Kubernetes と Slurm は、受け取ったジョブをクラスタの中のどのノードで動かすかを決めます。Kubernetes に出すときの形は、資源の要求と置き場所の条件を書いた Pod の定義で、Kubernetes の API サーバーに出します。Slurm に出すときは sbatch と srun を使います。そのため、SkyPilot は Kubernetes や Slurm を置き換えるものではありません。 Kueue との関係 Kueue は、Kubernetes のクラスタの中でジョブを待ち行列に並べ、割り当て枠や優先度に従って、受け入れるか、待たせるかを決める仕組みです。SkyPilot はどのクラスタやクラウドに置くかを選び、Kueue は選ばれたクラスタの中でいつ受け入れるかを決め、置くノードは Kubernetes のスケジューラが決めます。 決めることが違うので、1 つのクラスタの中では、SkyPilot と Kueue は置き換えではなく重ねて使います。Kueue の仕組みと、kube-scheduler や Volcano、KAI-Scheduler といった他のスケジューラとの関係は「Kubernetes の分散ジョブスケジューラ比較」で説明しています。v0.14.0 での連携の変更は、Kueue との連携の改善で説明します。 Kueue には、複数のクラスタにジョブを振り分ける MultiKueue もあります。MultiKueue もどのクラスタで動かすかに関わるので、SkyPilot とどう受け持ちを分け、どう組み合わせるかは、今後調べます。 ジョブグループのアップデート 動的なジョブグループ ジョブグループは、学習と報酬の計算のように資源の違う複数のタスクを同時に動かし、1 つの単位として管理する仕組みです。v0.14.0 では、動いているグループの中から新しいマネージドジョブを投げると、そのジョブも既定でグループの一部になり、グループを取り消すと一緒に止まります。 この変更は、OS のプロセスグループに例えるとわかりやすいです。v0.13.0 までは、学習の途中でグループの中から評価のジョブを投げると、そのジョブは setsid で別のプロセスグループに切り離して起動したプロセスのようなもので、グループを取り消しても動き続けました(図の左)。v0.14.0 では、グループの中から投げたジョブは、既定で同じグループに加わります。プロセスグループ全体に kill を送ると中のプロセスがすべて止まるのと同じように、人がグループを取り消すと、途中で加わった評価のジョブも取り消されます(図の右)。 具体的な流れは次のとおりです。 学習のタスクが、チェックポイントを共有の場所に書きます。 見張り役のタスクが、新しいチェックポイントを見つけます。 見張り役が sky jobs launch で評価のジョブを投げます。 そのジョブは自動でグループの新しいタスクになり、sky jobs queue ではグループの下に並びます。 評価のジョブは、学習とは別の資源で動き、状態も別に持ちます。 グループを取り消すと、評価のジョブも一緒に止まります。 例えと違う点もあります。止める単位は、ジョブを投げたタスクではなくグループそのものです。伝わるのはグループから評価のジョブへの一方向だけで、評価のジョブが失敗してもグループは失敗しません。また、実際に伝わるのはシグナルではなく、SkyPilot によるマネージドジョブの取り消しです。 この動きは、リモートの API サーバーが、マネージドジョブを専用の管理役のクラスタではなく自分で管理する構成(統合モード)で、評価のジョブを投げるタスクからその API サーバーに接続できる場合です。統合モードでない環境では、グループの中から投げたジョブはグループに加わらず、普通のジョブとして動きます。 slime の例で見るジョブグループ slime は、LLM を強化学習で鍛えるフレームワークで、重みを更新する学習の部分と、エージェントの応答を生成する推論の部分(LLM の推論サーバー SGLang)に分かれます。この例では、リポジトリの不具合を直すコーディングエージェントを鍛えます。SkyPilot の slime の例は、学習を 1 つのジョブ、SGLang エンジンを 1 つずつ別のジョブにしてジョブグループで束ね、SGLang エンジンの数と置く GPU を学習と別に決められるようにしたものです。図は、この例(Apache 2.0)から引用しました。 これは実行中にジョブを足す例ではなく、学習と推論のジョブを起動前に YAML に書き、ジョブグループでまとめて動かす例です。学習のジョブ(H100 が 4 枚)と SGLang エンジンのジョブ(H100 が 1 枚ずつ)は同じ Kubernetes のクラスタに置かれ、グループの中の通信でつながります。学習のジョブは、各 SGLang エンジンの /health が応答するのを待ってから、sglang-0.<グループ名>:30000 のようなグループのホスト名を slime に渡し、学習のジョブの中のプロセスを束ねる Ray に、slime の学習を投げます。 図の番号は、エージェントが課題を 1 回解いてから、重みが更新されて SGLang エンジンに届くまでの流れです。 学習のジョブの中の、エージェントに課題を解かせて rollout(1 回の試行の記録)を集める管理役(RolloutManager、CPU で動く)が、エージェントのループを回します。エージェントは毎ターン、生成の依頼を SGLang エンジンに配るルーターを通して生成を頼みます。RolloutManager は、生成したトークンと、その確率の対数である logprob を記録します。 エージェントは、リポジトリの取り出しやツールのコマンドを、信用できないコードを隔離して動かす Pod である SkyPilot Sandboxes の中で実行します。最後に、エージェントが作った差分を隠されたテストに当てて採点し、報酬を決めます。 trajectory と logprob と報酬が、学習側に渡ります。 学習側の学習ライブラリ Megatron が、強化学習の更新方法の 1 つ GRPO で重みを更新します。 新しい重みを、学習のジョブと SGLang エンジンのジョブの両方がマウントする共有のボリューム(/shared/policy)に書きます。 各 SGLang エンジンが、そのボリュームから新しい重みを読み込みます。 5 と 6 は既定の設定(WEIGHT_TRANSPORT=disk)の流れで、nccl を選ぶと、SGLang エンジンが学習のジョブと GPU 間の通信ライブラリ NCCL でつながって重みを受け取ります。 ジョブグループと Ray は、決めることが違います。 ジョブグループ(SkyPilot) Ray(slime の中) 決めること どのクラスタに、どのジョブを、いくつ立て、いつ一緒に止めるか 1 つのジョブの中で、どの GPU をどのプロセスに割り当てるか この例での中身 学習のジョブ 1 つと SGLang エンジンのジョブを立て、互いをホスト名で見つけられるようにする 学習のジョブの中で、Megatron の学習プロセスに GPU を割り当てる。rollout の管理役は CPU で動かす SGLang エンジンを外に出さず、学習と推論を SkyPilot の 1 つのタスクの中で動かす構成なら、ジョブグループを使わずに組めます。そのタスクの中では、slime が Ray に学習用と推論用の GPU を割り当てさせます。同じ GPU を共有させても、別々の GPU に分けても構いません。SGLang エンジンを学習と別に増やしたいときや、別の種類の GPU に置きたいときに、SGLang エンジンをジョブグループの別のジョブに出し、slime の外部エンジンの設定(--rollout-external-engine-addrs)にそのホスト名を渡します。このとき Ray が割り当てるのは、学習のジョブの GPU だけです。 Kubernetes 関連のアップデート AWS Neuron への対応 v0.14.0 から、Kubernetes の上の Trainium のノードにも、GPU と同じ accelerators: の書き方でジョブを置けます。これまで SkyPilot が Kubernetes で扱えるアクセラレータは NVIDIA と AMD の GPU と Google の TPU だけで、Trainium のノードは空いていても使えませんでした。Neuron は、AWS のアクセラレータ Trainium を動かすソフトウェアの名前で、Kubernetes にはこの名前の資源として見えます。 受け持ちは次のとおりです。クラスタを運用する側は、Neuron 用の AMI で起動するノードと、Trainium を Kubernetes の資源として見せる Neuron のデバイスプラグインを用意します。SkyPilot は、Pod を Trainium のノードで動かすために、図の 1 から 3 を Pod の定義に書きます。1 つ目に、Pod が Trainium のチップを何枚使うかを Kubernetes に伝えます。2 つ目に、Pod が Trainium のノードだけに置かれるように条件を付けます。3 つ目に、Neuron のノードには Neuron を使わない Pod を入れないための印が付けられていることがあり、この Pod はその印があっても入れるようにします。ノードを自動で増減させる Karpenter を使い、そのことを SkyPilot の設定で知らせているクラスタでは、2 つ目の条件は Karpenter が付けるノードのラベルで書かれるので、ノードがまだ無くても Karpenter が Trainium のノードを作る手がかりになります。 Kubernetes の既定のコンテナイメージは、Trainium の Pod でも GPU 用のもので、Neuron SDK は入っていません。そのため、image_id で Neuron SDK の入ったイメージを指定します。 Trainium に投げるコードの側では、PyTorch を Trainium で動かす TorchNeuron が公開ベータになりました。ブログの学習の例では、変更は model.to('neuron') の 1 行です。TorchNeuron 向けに直した PyTorch の学習スクリプトを、SkyPilot のタスクの run から Trainium のノードで動かせるかは、今後検証してみようと思います。 EFA の改善 EFA は Elastic Fabric Adapter の略で、AWS のノードどうしを高速につなぐネットワークのインタフェースです。v0.14.0 では、複数ノードの学習が EFA を使えないまま動いてしまう 2 つの場合を、SkyPilot が防ぐようになりました(図)。1 つは、アクセラレータのノードがまだ 0 台で、Pod に書く EFA の数が決まらない場合です。もう 1 つは、Pod が別々の AZ に散って、EFA でつながらない場合です。前者では SkyPilot が EFA の数をカタログから決め、後者では Pod の置き場所を 1 つの AZ にそろえます。SkyPilot が受け持つのは Pod に書く EFA の要求の数と置き場所までで、割り当てられた EFA をアプリケーションが実際に使うかは、イメージの中の通信ライブラリの設定で決まります。 SkyPilot が EFA を要求するのは、タスクの resources: の下に、使える最速のネットワークを頼む設定 network_tier: best を書いたときです。頼んだ種類のアクセラレータを頼んだ数以上に持つノードが vpc.amazonaws.com/efa の資源を公開していれば、要求する数は次の式で決まります。 \text{要求する EFA の数} = \max\left(1,\ \left\lfloor \frac{\text{頼んだアクセラレータの数}}{\text{ノードのアクセラレータの数}} \times \text{ノードの EFA の数} \right\rfloor\right) この計算は、頼んだアクセラレータの数で割合を出します。たとえば p5.48xlarge は GPU を 8 枚、EFA を 32 公開するので、H100:4 を頼めば EFA は 16 になります。 1 つ目の改善は、アクセラレータのノードが 0 台でも数を決めることです。これまでは動いているノードを調べて数を決めていたので、Karpenter などでノードを 0 台から増やすクラスタでは数が決まらず、EFA を要求しないまま Pod が作られることがありました。そうなると、GPU 間の通信ライブラリ NCCL の通信は、気づかないまま TCP に落ちます。v0.14.0 からは、ノードを自動で増減させる仕組みを使っていることを設定 kubernetes.autoscaler で SkyPilot に知らせたクラスタでは、AWS のノードが 1 台でもあれば、カタログから数を決めます。カタログは、SkyPilot が持つインスタンスの種類ごとの一覧表です。SkyPilot は、要求を載せられるインスタンスのうち、アクセラレータ 1 つあたりの EFA が最も少ないものに合わせて、同じ割合で数を決めます。カタログでも数が決まらなければ、これまでどおり EFA なしの Pod になります。 2 つ目の改善は、複数ノードの EFA のジョブを 1 つの AZ にまとめることです。EFA の通信は 1 つの AZ の中で組むので、ノードが別々の AZ に散ると EFA でつながらず、TCP に落ちるか、通信を始められません。v0.14.0 からは、AWS のノードでできた Kubernetes のクラスタで複数ノードの network_tier: best のジョブを投げると、SkyPilot は Pod の定義に、同じジョブの他の Pod と同じ AZ に置く条件(podAffinity)を足します。最初の Pod が置かれた AZ に、残りの Pod が続きます。この条件は必須なので、その AZ に空きが無ければ、Pod は TCP に落ちて動き出すのではなく、待ちの状態で止まります。 Kueue との連携の改善 これまでは、Kueue の待ち行列で順番を待っている時間も、SkyPilot が計算資源の確保の時間に数えていたので、確保のタイムアウトを短く書くと、割り当て枠が空くのを待っているだけのジョブまで、確保の失敗として捨てられていました。v0.14.0 からは、Kueue の受け入れを待っている間は確保の時計を止め、受け入れられてから数え始めます。 Slurm 関連のアップデート 複数ユーザーでの実行 v0.14.0 では、SkyPilot が Slurm にジョブを出すとき、依頼した人それぞれの Unix アカウントとして出せます。これまでは、1 つの SkyPilot の API サーバーで Slurm のクラスタを分け合うと、全員が設定ファイル ~/.slurm/config に書いた 1 つの SSH ユーザーとして出ていたので、Slurm の利用量の記録(accounting)や公平な割り当て(fairshare)、ファイルの権限が、全員を同じ 1 人として扱っていました。 有効にするには、API サーバーが読む SkyPilot の設定で slurm.submit_as_user を true にします。すると SkyPilot は、まず SSH ユーザーで接続し、そのあと確保、srun、ファイルの転送、取り消しを、依頼した人の Unix アカウントとして行います。アカウント名は、既定ではメールアドレスの @ より前の部分で、username_map で個別に対応を書けます。次の例は、Slurm のクラスタに jdoe の Unix アカウントがあることを前提にしています。 slurm: submit_as_user: true username_map: jane.doe@example.com: jdoe そのためには、SSH ユーザーが root であるか、対象のユーザーとして /bin/bash をパスワードなしの sudo で動かせる必要があります。SkyPilot はこのシェルの中でスクリプトの実行や rsync を行うので、コマンドごとには絞れず、切り替え先の権限がそのまま SSH ユーザーに渡ります。ドキュメントは、切り替え先を sudo や Slurm の管理権限を持たない専用グループのアカウントに限り、sudo に端末を要求させる設定 requiretty を、そのグループにだけ外す設定例を載せています。共通のアカウントで運用するなら、既定の submit_as_user: false のままで構いません。 あわせて、Slurm 側で利用量を付ける先(account)と、優先度や上限の枠(QoS)を、SkyPilot のワークスペース(ユーザーやプロジェクトを分ける単位)ごとに指定できるようになりました。この指定は slurm.quota に書き、SkyPilot が sbatch の --account と --qos に渡します。この account は Slurm の利用量を付ける先の単位で、Unix のアカウントとは別のものです。 コンテナクラスタの停止と再開 SkyPilot は Slurm に割り当てさせたノードの上に自分のクラスタを立て、タスクにコンテナイメージを書いた場合は、そのクラスタをコンテナの中に立てます。v0.14.0 では、このコンテナのクラスタを、入れたパッケージやファイルを残したまま止めて、あとで再開できます。止めている間は Slurm のノードの割り当てを手放すので、ノードを他の人に返せます。 sky stop と sky start で止めるときは、各ノードのコンテナのファイルシステムを共有のストレージに写してから割り当てを手放し、再開するときは新しい割り当てに書き戻します。残るのはファイルシステムで、動いていたプロセスは止めた時点で終わるので、計算を途中から続けるにはチェックポイントが要ります。対象は、Slurm でコンテナを動かすプラグイン Pyxis を使うクラスタです。あわせて、一定時間使われていないクラスタを同じ手順で止める autostop と、ホストのパスをマウントする設定も入りました。 まとめ 筆者は v0.14.0 の動きの多くをまだ実機で確かめておらず、実際に動かして確かめるしかないので、次の点を調べる予定です。 今後検証すること 確かめたいこと AWS PCS、SageMaker HyperPod、Amazon EKS を登録して使う それぞれを SkyPilot に登録し、同じタスクの YAML で投げ分けられるか。PCS で計算ノードを 0 台から増やす構成が通るか slime(または同じ作りのフレームワーク miles)とジョブグループを組み合わせる SGLang エンジンをジョブグループの別のジョブにし、外部エンジンとして学習側に渡したときに、学習が回り、重みの受け渡しが動くか Neuron と GPU のノードにジョブを投げ分ける 同じ API サーバーから、Kubernetes の上の Trainium のノードと GPU のノードに、別々のタスクを投げ分けられるか EFA の挙動 network_tier: best で、アクセラレータのノードが 0 台からでも EFA の数が決まるか、複数ノードの Pod が 1 つの AZ にまとまるか MultiKueue との組み合わせ 複数のクラスタへの振り分けを、SkyPilot と MultiKueue がそれぞれどう受け持つか 参考 SkyPilot v0.14.0 のリリースノート SkyPilot のドキュメント ジョブグループのドキュメント Kubernetes で AWS Neuron に対応させた PR #10169 Introducing TorchNeuron: Native PyTorch backend for AWS Trainium Neuron を EKS で使う手順 Karpenter のインスタンスタイプの表