Pathways on Cloud のトラブルシューティング

このページでは、機械学習(ML)エンジニアとプラットフォーム管理者が Google Cloudで Pathways ワークロードの問題を診断して解決する方法について説明します。このガイドでは、コンポーネント ログの検査、クラスタとスライスの準備状況の確認、Megascale XLA(MXLA)転送指標のモニタリング、一般的なランタイム エラーの修正について説明します。各セクションで、環境の [GKE] タブまたは [Cluster Director] タブを選択します。

始める前に

始める前に

GKE

先に進む前に、次の前提条件を満たしてください。

Cluster Director

先に進む前に、次の前提条件を満たしてください。

ログを表示

GKE

gcluster job logs コマンドを使用して、Pathways ワークロードのログを直接表示できます(ワーカー Pod のログを含めるには --main-only=false を渡します)。

gcluster job logs WORKLOAD_NAME \
    --cluster=CLUSTER \
    --project=PROJECT_ID \
    --location=LOCATION \
    --main-only=false

次のように置き換えます。

  • WORKLOAD_NAME: Cluster Toolkit を使用する場合はワークロードの名前。kubectl を使用する場合は JobSet 名。
  • CLUSTER: GKE クラスタの名前。
  • PROJECT_ID: 実際のGoogle Cloud プロジェクト ID。
  • LOCATION: GKE クラスタを作成したリージョンまたはゾーン。

kubectl を使用してワークロードのすべての Pod を一覧表示するには、JobSet 名ラベルでフィルタします。

kubectl get pods \
    -l jobset.sigs.k8s.io/jobset-name=WORKLOAD_NAME

ワークロードのステータスを確認するか、失敗したジョブを一覧表示するには、gcluster job list コマンドを使用します。

gcluster job list --status Failed \
    --cluster=CLUSTER \
    --project=PROJECT_ID \
    --location=LOCATION

または、Cloud Logging のログ エクスプローラで、プロジェクト、ロケーション、クラスタ、ワークロードに合わせて調整した次のクエリを実行します。

resource.type="k8s_container"
resource.labels.project_id="PROJECT_ID"
resource.labels.location="LOCATION"
resource.labels.cluster_name="CLUSTER"
resource.labels.namespace_name="default"
resource.labels.pod_name:"WORKLOAD_NAME"

このクエリは、pathways-rm、pathways-proxy、pathways-worker、workload-container などの名前を持つ複数の Pathways Kubernetes コンテナと一致します。問題の原因となっているコンテナを特定するには、resource.labels.container_name:"CONTAINER_NAME" などのコンテナ名フィルタを追加します。ここで、CONTAINER_NAME はコンテナの名前です。

Cluster Director

Pathways スクリプトは、共有ファイル システムにログを書き込みます。

  • Pathways サービスジョブは、sbatch を実行したディレクトリ(~/pathways など)に pathways-service-SERVICE_JOB_ID.out と pathways-service-SERVICE_JOB_ID.err を書き込みます。
  • Pathways リソース マネージャー、IFRT プロキシ サーバー、TPU ワーカーは、~/pathways/service_SERVICE_JOB_ID/logs に書き込みます。これには、rm.log、proxy.log、ワーカータスクごとに 1 つの slice-*.out ファイルと slice-*.err ファイルが含まれます。
  • サンプルの MaxText ワークロードは、ログを maxtext-llama31-JOB_ID.err に書き込みます。

次のように置き換えます。

  • SERVICE_JOB_ID: Pathways サービスジョブの Slurm ジョブ ID。sbatch start_pathways.sh が出力します。
  • JOB_ID: MaxText ジョブの Slurm ジョブ ID。sbatch run_maxtext.sh が出力します。

ログインノードで、Pathways ジョブの状態を確認し、ジョブ ID を見つけます。

squeue -u ${USER}

Pathways のコンポーネントと指標をモニタリングする

以降のセクションは、GKE の Pathways に適用されます。

稼働状況のモニタリング

コンテナログのエントリを調べることで、さまざまな Pathways コンポーネントの状態をモニタリングできます。

pathways-proxy コンテナは、次のログエントリを書き込むと、新しい接続リクエストを処理する準備が整います。ログを表示するには、次のコマンドを実行します。

kubectl logs HEAD_POD_NAME --container pathways-proxy

HEAD_POD_NAME は、Pathways ヘッド Pod の名前に置き換えます。

出力には、次のような行が含まれます。

I1101 04:51:41.967764       1 proxy_server.cc:125] IFRT proxy server started with status OK

pathways-rm コンテナは、次のログエントリを書き込むと、新しい接続リクエストを処理する準備が整います。

kubectl logs HEAD_POD_NAME --container pathways-rm

出力には、次のような行が含まれます。

I1101 04:50:41.967764       1 server_lib.cc:1473] Pathways Server serving on POD_IP:29001

POD_IP は Pod の IP アドレスです。Pod が再起動または再スケジュールされると、このアドレスは変更される可能性があります。

すべての TPU スライスの準備が完了していることを確認するには、pathways-rm コンテナログで Pathways Slices Now Ready を確認します。

kubectl logs HEAD_POD_NAME --container pathways-rm

たとえば、次のログエントリは、2 つのスライスのうち 2 つの準備が完了していることを示しています。

I1101 04:52:41.967764       1 multi_job_allocator.cc:1063] *** 2/2 Pathways Slices Now Ready ***

Pathways クライアントは、すべてのスライスが準備できていなくても、プロキシ サーバーの準備が整うとすぐに IFRT プロキシ サーバーに接続できます。ジョブは、TPU スライスの準備が整うまで仮想スライスで動作します。仮想スライスを使用すると、TPU が使用できないときにコードを実行できます。

pathways-worker コンテナの準備が完了していることを確認するには、ログを確認します。

kubectl logs WORKER_POD_NAME --container pathways-worker

WORKER_POD_NAME は、Pathways ワーカー Pod の名前に置き換えます。

ワーカーの準備が整うと、出力には次のような行が含まれます。

I1101 04:50:41.967764       1 server_lib.cc:1473] Pathways Server serving on POD_IP:29005

POD_IP は Pod の IP アドレスです。Pod が再起動または再スケジュールされると、このアドレスは変更される可能性があります。

指標の収集

Pathways は、デバッグのために低レベルのシステム指標を Cloud Monitoring に書き込むことができます。指標には、次の内容が含まれます。

  • データセンター ネットワーク(DCN)転送レイテンシ
  • グループ レイテンシ
  • ホストからデバイスへの転送レイテンシ
  • デバイスからホストへの転送レイテンシ

指標は、GKE クラスタが実行されているGoogle Cloud プロジェクトの Monitoring ダッシュボードで確認できます。

Metrics Explorer でこれらの指標をモニタリングする手順は次のとおりです。

  1. Google Cloud コンソールで、[Metrics Explorer] ページに移動します。
  2. [指標を選択] フィールドで、指標の名前でフィルタします。
  3. ワークロード名と期間でフィルタするには、[フィルタを追加] をクリックし、pod_name でフィルタします。
  4. [集計] で、モニタリングする指標とワークロードに基づいて集計タイプを選択します。

DCN 転送レイテンシ

この Megascale XLA(MXLA)指標は、マルチスライス トラフィックのネットワーク転送レイテンシの累積分布を測定します。レイテンシの測定は、システムが DCN 経由でデータを転送するリクエストを発行したときに開始され、データ転送が完了したことを示す確認応答を受信したときに終了します。この指標をモニタリングするには、dcn_transfer_latencies 指標名でフィルタします。

グループ レイテンシ

この MXLA 指標は、マルチスライス トラフィックのエンドツーエンドの全体的なレイテンシの累積分布を測定します。レイテンシの測定は、システムがグループ オペレーションのリクエストを発行したときに開始され、データ転送が完了したことを示す確認応答を受信したときに終了します。この指標をモニタリングするには、collective_end_to_end_latencies 指標名でフィルタします。

ホストからデバイスへの転送レイテンシ

この MXLA 指標は、マルチスライス トラフィックのホストからデバイスへの転送レイテンシの累積分布を測定します。レイテンシの測定は、システムがホストから TPU デバイスにデータを転送するリクエストを発行したときに開始され、データ転送が完了したという確認応答を受信したときに終了します。この指標をモニタリングするには、host_to_device_transfer_latencies 指標名でフィルタします。

デバイスからホストへの転送レイテンシ

この MXLA 指標は、マルチスライス トラフィックのデバイスからホストへの転送レイテンシの累積分布を測定します。レイテンシの測定は、システムが TPU デバイスからホストにデータを転送するリクエストを発行したときに開始され、データ転送が完了したことを示す確認応答を受信したときに終了します。この指標をモニタリングするには、device_to_host_transfer_latencies 指標名でフィルタします。

一般的なエラーをデバッグする

GKE

アクセラレータ構成の警告をハッシュ化できない

次のメッセージは警告のみであり、JAX コードのパフォーマンスには影響しません。

INFO:jax._src.cache_key:get (_hash_accelerator_config): unable to hash accelerator config, falling back to hashing devices + platform: UNIMPLEMENTED: GetTopologyForDevices is not supported for the IFRT proxy client. (type <class 'jaxlib.xla_extension.XlaRuntimeError'>)

リソースに対する権限 logging.logEntries.create が拒否されました

次のエラーが表示された場合は、Vertex AI Workbench で使用される Compute Engine サービス アカウントに、Logging にログエントリを書き込む権限があることを確認します。

INFO:absl:Created 'ArrayHandler' with primary_host=0, replica-id=0
WARNING:absl:pathwaysutils: Detected Pathways-on-Cloud backend. Applying changes.
Failed to submit 1 logs.
Traceback (most recent call last):
  File "/opt/conda/lib/python3.10/site-packages/google/api_core/grpc_helpers.py", line 65, in error_remapped_callable
    return callable_(**args, **kwargs)
  File "/opt/conda/lib/python3.10/site-packages/grpc/_channel.py", line 1181, in __call__
    return _end_unary_response_blocking(state, call, False, None)
  File "/opt/conda/lib/python3.10/site-packages/google/api_core/grpc_helpers.py", line 1006, in _end_unary_response_blocking
    raise _InactiveRpcError(state) # pytype: disable-not-instantiable
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
  status = StatusCode.PERMISSION_DENIED
  details = "Permission 'logging.logEntries.create' denied on resource (or it may not exist)."
  debug_error_string = "UNKNOWN:Error received from peer ipv4:216.239.34.174:443 {created_time:"2024-10-03T20:30:44.820425276+00.00", grpc_status:7, grpc_message:"Permission \'logging.logEntries.create\' denied on resource (or it may not exist)."}"
>

この問題を解決するには、Compute Engine サービス アカウントにログ書き込み(roles/logging.logWriter)ロールを付与します。

IFRT プロキシ サーバーに接続できない

IFRT コマンドを Pathways クラスタに送信する最初の JAX コマンドを実行しようとすると、約 1 分間応答が停止し、次のような RuntimeError が表示されることがあります。

RuntimeError: Unable to initialize backend 'proxy': UNAVAILABLE: Unable to establish connection to ifrt_proxy server, please check provided address example-workload-proxy-0-0.example-workload.default.svc.example-cluster-domain.:38676'; detailed error: DNS resolution failed (set JAX_PLATFORMS='' to automatically choose an available backend)

このエラーが表示された場合は、IFRT プロキシ クライアントが IFRT プロキシ サーバーに接続できません。以下を確認します。

  • Virtual Private Cloud(VPC)ネットワークが正しく構成されていることを確認します。
  • ファイアウォール ルールで接続が許可されていることを確認します。
  • Pathways クラスタがプロビジョニングされていることを確認します。
  • コンテナログで起動エラー メッセージを確認します。

IFRT プロキシ サーバーに接続するときに ALTS handshake が失敗したか、ソケットが閉じられた

Workload Identity Federation for GKE ノードプールで hostNetwork: true フィールドを指定せずにカスタム マニフェストを実行すると、Alts handshake failed (TSI_INTERNAL_ERROR) または UNAVAILABLE: Unable to establish connection to ifrt_proxy server ... Socket closed が表示されることがあります。この問題を解決するには、pathways-proxy コンテナと JAX クライアント コンテナの両方で IFRT_PROXY_USE_INSECURE_GRPC_CREDENTIALS: "true" 環境変数を設定します(両側が一致する必要があります)。この環境変数を追加すると、ALTS が無効になり、代わりに安全でない gRPC が使用されます。そのため、信頼できるクラスタ ネットワーク内でのみ使用してください。

Pathways クラスタへの既存の接続がある

Pathways クラスタは、一度に 1 つのクライアントとのみセッションを維持できます。2 つの別々のノートブックが同じ Pathways クラスタに接続しようとすると、1 つは接続され、もう 1 つは次のエラーが表示されます。

INFO:absl:Created ArrayHandler with primary_host=0, replica_id=0
WARNING:absl:pathwaysutils: Detected Pathways-on-Cloud backend. Applying changes.
E0927 21:19:52.919607   37624 rpc_helper.cc:56] Connection to IFRT proxy server was terminated: CANCELLED: Cancelled
E0927 21:20:03.467547   37719 rpc_helper.cc:56] Connection to IFRT proxy server was terminated: CANCELLED: Cancelled
E0927 21:20:14.011645   37807 rpc_helper.cc:56] Connection to IFRT proxy server was terminated: CANCELLED: Cancelled
E0927 21:20:24.557955   37924 rpc_helper.cc:56] Connection to IFRT proxy server was terminated: CANCELLED: Cancelled
---------------------------------------------------------------------------
XlaRuntimeError                           Traceback (most recent call last)
File /opt/conda/lib/python3.10/site-packages/jax/_src/xla_bridge.py:887, in backends()
    885   continue
--> 887 backend = _init_backend(platform)
    888 _backends[platform] = backend

File /opt/conda/lib/python3.10/site-packages/jax/_src/xla_bridge.py:973, in _init_backend(platform)
    972 logger.debug("Initializing backend '%s'", platform)
--> 973 backend = registration.factory()
    974 # TODO: consider raising more descriptive errors directly from backend
    975 # factories instead of returning None.

File /opt/conda/lib/python3.10/site-packages/pathwaysutils/proxy_backend.py:24, in register_backend_factory.<locals>.<lambda>()
     21 def register_backend_factory():
     22   xla_bridge.register_backend_factory(
     23       "proxy",
---> 24       lambda: ifrt_proxy.get_client(
     25           jax.config.read("jax_backend_target"),
     26           ifrt_proxy.ClientConnectionOptions(),
     27       ),
     28       priority=-1,
     29   )

XlaRuntimeError: UNAVAILABLE: Unable to establish connection to ifrt_proxy server, please check provided address example-workload-proxy-0-0.example-workload.default.svc.example-cluster-domain.:38676'; detailed error: Connection to IFRT proxy server was terminated: CANCELLED: Cancelled

During handling of the above exception, another exception occurred:

RuntimeError                              Traceback (most recent call last)
Cell In[2], line 4
      1 import pathwaysutils
      3 import jax
----> 4 print(jax.devices())

File /opt/conda/lib/python3.10/site-packages/jax/_src/xla_bridge.py:1085, in devices(backend)
   1060 def devices(
   1061     backend: str | xla_client.Client | None = None
   1062 ) -> list[xla_client.Device]:
   1063   """Returns a list of all devices for a given backend.
   1064
   1065   .. currentmodule:: jaxlib.xla_extension
   (...)
   1083     List of Device subclasses.
   1084   """
-> 1085   return get_backend(backend).devices()

File /opt/conda/lib/python3.10/site-packages/jax/_src/xla_bridge.py:1019, in get_backend(platform)
   1015 @lru_cache(maxsize=None)  # don't use util.memoize because there is no X64 dependence.
   1016 def get_backend(
   1017     platform: None | str | xla_client.Client = None
   1018 ) -> xla_client.Client:
-> 1019   return _get_backend_uncached(platform)

File /opt/conda/lib/python3.10/site-packages/jax/_src/xla_bridge.py:998, in _get_backend_uncached(platform)
    994   return platform
    996 platform = (platform or _XLA_BACKEND.value or _PLATFORM_NAME.value or None)
--> 998 bs = backends()
    999 if platform is not None:
   1000   platform = canonicalize_platform(platform)

File /opt/conda/lib/python3.10/site-packages/jax/_src/xla_bridge.py:903, in backends()
    901       else:
    902         err_msg += " (you may need to uninstall the failing plugin package, or set JAX_PLATFORMS=cpu to skip this backend.)"
--> 903       raise RuntimeError(err_msg)
    905 assert _default_backend is not None
    906 if not config.jax_platforms.value:

RuntimeError: Unable to initialize backend 'proxy': UNAVAILABLE: Unable to establish connection to ifrt_proxy server, please check provided address 'example-workload-proxy-0-0.example-workload.default.svc.example-cluster-domain.:38676'; detailed error: Connection to IFRT proxy server was terminated: CANCELLED: Cancelled (set JAX_PLATFORMS='' to automatically choose an available backend)

元のクライアントが切断されると、2 番目のクライアントが接続できるようになります。予期しない切断が発生した場合は、他のクライアントが接続できるように、Pathways クラスタの再起動が必要になることがあります。

LocalProxy.__init__() に予期しないキーワード引数 'unbound_message' が指定された

pathwaysutils のインポート後に次のエラーが表示された場合は、古いバージョンの Flask または Werkzeug が環境にインストールされているかどうかを確認します(必要に応じて pip3 を pip に置き換えます)。

pip3 list --outdated

Flask または Werkzeug がリストされている場合は、パッケージをアップグレードします(アップグレードすると、プロジェクト内の他のパッケージや依存関係に影響する可能性があります)。

pip3 install --upgrade flask Werkzeug

プロキシ サーバーからの内部エラー

"Internal error from proxy server during Array::IsDeleted(): UNAVAILABLE:Connection to IFRT proxy server was terminated: FAILED_PRECONDITION:
GrpcClientSession: writes no longer allowed."

このエラーは、IFRT プロキシ サーバーがクライアントから切断されたことを示します。この問題を解決するには、クライアントを再起動します。ノートブックの場合は、ノートブック カーネルを再起動してノートブックを再実行します。

SIGTERM と HBM OOM

RESOURCE_EXHAUSTED エラーに関連するログの SIGTERM エントリは、高帯域幅メモリ(HBM)のメモリ不足(OOM)エラーを示している可能性があります。この場合は、JAX コードで使用する HBM の量を減らします。

INVALID_ARGUMENT

"INVALID_ARGUMENT : Permanent error, with a last message of Lifecycle
matches_prefix cannot specify more than 50 prefixes per config.; Error while
initializing persistent cache storage Cloud Storage"

このエラーは、--pathways-gcs-location フラグに渡された Cloud Storage バケットがライフサイクル ポリシーの上限(50 接頭辞)に達した場合に発生します。この問題を解決するには、使用しなくなった Cloud Storage ライフサイクル ポリシーを削除します。

永続的なエラー

Permanent error, with a last message of The specified bucket does not exist.; Error while initializing persistent cache storage gcs

Pathways コンテナに無効な Cloud Storage のロケーションを指定すると、Pathways リソース マネージャーまたは Pathways ワーカーがこのエラーを出力します。

デーモンからのエラー レスポンス

Error response from daemon: dockerfile parse error line 16: Unknown flag: exclude

このエラーは、古いバージョンの Docker を使用している場合に発生します。Docker のバージョンをアップグレードします。

IFRT プロキシ クライアントとサーバーが一致しない

IFRT Proxy client and server failed to agree on the protocol version; supported versions: client = [1, 1], server = [3, 14]

このエラーは、古いバージョンの MaxText を使用していることを示します。最新の MaxText イメージを再ビルドします。

Cluster Director

setup_env.sh が Enroot mktemp エラーで失敗する

setup_env.sh が次のエラーで失敗した場合、Enroot の一時ディレクトリが存在しません。

mktemp: failed to create directory via template '/tmp/UID/tmp/enroot...'

この問題を解決するには、mkdir -p /tmp/$(id -u)/tmp を実行してから、スクリプトを再度実行します。

setup_env.sh が Pathways イメージを pull できない

setup_env.sh が Couldn't pull ... で失敗した場合、リクエストされた JAX_VERSION に Pathways 画像がタグ付けされていません。サポートされている JAX バージョンを使用します。

クラスタに cpu パーティションがない

sinfo に cpu パーティションが表示されない場合、クラスタ定義に CPU ノードセットがないか、パーティションの名前が異なります。Pathways スクリプトは、cpu という名前のパーティションにジョブを送信します。この問題を解決するには、クラスタ ブループリントを更新して cpu という名前の CPU パーティションを定義し、クラスタを再デプロイします。または、Pathways ジョブ スクリプトのパーティション名を更新して、sinfo で示される CPU パーティションと一致させます。

TPU ノードが起動しない

予約がクラスタのゾーンにあり、十分な ct6e-standard-4t VM があり、staticNodeCount と acceleratorTopology が一致していることを確認します。

Pathways サービスが Invalid partition name specified で終了する

PARTITION 変数が間違っています。sinfo の出力から TPU パーティションを選択します。

Pathways サービスが準備完了にならない

サービスログが Waiting for at least MIN_SLICES=... のままである場合、実行されているスライスが不足しています。次のコマンドの NODELIST(REASON) 列に、使用可能な容量がない、SLICE_SHAPE 値が TPU ノードセットと一致しないなどの理由が表示されます。

squeue -u ${USER} -n pw-slice

Pathways リソース マネージャーまたは IFRT プロキシ サーバーが起動しない

サービスが Timed out waiting for Pathways Resource Manager または Timed out waiting for Pathways IFRT Proxy Server で失敗した場合、Pathways コンテナは起動していません。ログ ディレクトリの rm.log と proxy.log を確認します。

Pathways サービスが予期せず停止する

サービスが The Pathways Resource Manager or IFRT proxy exited で停止した場合、いずれかのワーカーがクラッシュし、サービスがワーカーを停止したことを示します。ログ ディレクトリの rm.log と proxy.log を確認してから、サービスを再度起動します。

TPU ノードが不正な状態で停止している

ノードを復元するには、ログインノードで次のコマンドを実行します。

sudo scontrol update nodename=NODE \
    state=power_down_force

NODE は、sinfo で示されるノードの名前に置き換えます。

MaxText が実行中の Pathways サービスを検出できない

MaxText が No running Pathways service after 60 minutes で失敗した場合、サービスが実行されていないか、まだ準備ができていません。サービスログを確認します。さらに待機するには、run_maxtext.sh を送信するときに SERVICE_WAIT_MINUTES を設定します。

MaxText が RESOURCE_EXHAUSTED で失敗する

モデルが TPU メモリに収まらない。2x4 または 4x4 スライスを使用するか、REDUCED_LAYERS=1 を設定します。

MaxText ジョブが保留中のままになる

CPU ノードには、Pathways サービスが使用する 4 つの CPU と 80 GB のメモリに加えて、run_maxtext.sh がリクエストする 8 つの CPU と 160 GB のメモリがありません。両方のジョブが n2-highmem-32 ノードに収まります。この問題を解決するには、cpu パーティションの CPU とメモリの容量(またはノード数)を増やすか、run_maxtext.sh のリソース リクエストを減らします。

IFRT プロキシ サーバーに接続できない

クライアントが応答を停止するか、UNAVAILABLE で失敗した場合、プロキシ サーバーに到達できません。

  • サービスログに READY が表示されていることを確認します。
  • JAX_BACKEND_TARGET が ~/pathways/cluster.env のアドレスと一致していることを確認します。
  • ポート転送を使用している場合は、SSH トンネルがまだ実行されていることを確認します。
  • クライアントが VM で実行されている場合は、VM がクラスタのサブネット内にあることを確認します。次のコマンドが成功するはずです。

    nc -zv PROXY_IP 29000

    PROXY_IP は、サービスログの IFRT プロキシ IP アドレスに置き換えます。

jax.devices() が TPU デバイスではなく CPU デバイスを一覧表示する

jax をインポートした後に、JAX_PLATFORMS 環境変数と JAX_BACKEND_TARGET 環境変数を設定しました。ノートブック カーネルを再起動し、jax をインポートする前に変数を設定します。

IFRT プロキシ サーバーへの接続直後のエラー

クライアントの jax または pathwaysutils のバージョンが Pathways サーバーと一致していません。~/pathways/venv のバージョンをインストールします。

計算が DATA_LOSS と PlacementDataLoss で失敗する

計算で、実行されていないスライスのデバイスが使用されました。たとえば、スライスがプリエンプトされたためです。Slurm がスライスを再キューイングしている間、IFRT プロキシ サーバーは接続されたままになります。すべてのワーカータスクが実行されているかどうかを確認し、スライスが戻った後に計算を再度実行します。

squeue -u ${USER} -n pw-slice

Spot のプリエンプション後に計算が失敗する

プリエンプトされたスライスのデバイスを使用する計算は失敗します。Spot プリエンプションから自動的に復元するには、Pathways を使用した復元力のあるトレーニングの説明に従って、チェックポイントとエラスティック スライスの再スケーリングを構成します。

次のステップ