pathways-workload

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Pathways on Cloud Workload Debugging Skill

Cloud 上 Pathways 工作负载调试 Skill

This skill provides comprehensive instructions, debugging playbooks, and helper utilities to troubleshoot Pathways on Cloud GKE workloads.
此 skill 提供全面的说明、调试手册和辅助 工具,用于排查 Cloud GKE 工作负载中的 Pathways 问题。

Usage Attribution

使用归属说明

MUST READ: Before executing any
gcloud
, REST API, or MCP command, you MUST read and follow the instructions in Usage Attribution.

必须阅读:在执行任何
gcloud
、REST API 或 MCP 命令之前,你 必须阅读并遵循 使用归属说明中的指导。

Overview

概述

Understanding Initial Setup for JAX+Pathways on Cloud

了解 Cloud 上 JAX+Pathways 的初始设置

A GKE cluster is required to use Pathways. We have instructions to create one which utilize either 1) a one click setup like XPK or 2) a series of gcloud commands here: https://docs.cloud.google.com/ai-hypercomputer/docs/workloads/pathways-on-cloud/create-gke-cluster
Advanced customers have built custom infrastructure which rolls Pathways based JobSets and cluster creation commands. To debug their infra issues, we may want to ask them to share their jobset YAMLs with us (redacting their main container definition is fine).
使用 Pathways 需要一个 GKE 集群。我们提供了相关说明,可通过以下两种方式之一创建集群:1) 像 XPK 那样一键设置;或 2) 在此处执行一系列 gcloud 命令: https://docs.cloud.google.com/ai-hypercomputer/docs/workloads/pathways-on-cloud/create-gke-cluster
高级客户已经构建了自定义基础设施,其中会滚动部署基于 Pathways 的 JobSet,并包含集群创建命令。要调试其基础设施问题,我们可以请他们 分享 jobset YAML(可以隐藏主容器定义)。

Parsing Important Logs

解析重要日志

How to determine if various Pathways components have started successfully
IFRT Proxy Server (a.k.a Pathways Client) Ready
IFRT proxy server started with status OK

Pathways worker Ready: Pathways Server serving on [::]:29001
RM (Resource Manager) Ready and eventually all TPU slices are ready
Pathways Server serving on [::]:29001
...
...
***<num slices>/<num slices> Pathways Slices Now Ready ***
Individual Pathways worker (on a TPU host) Ready
Pathways Server serving on [::]:29001

如何判断各个 Pathways 组件是否已成功启动
IFRT Proxy Server(也称 Pathways Client)已就绪
IFRT proxy server started with status OK

Pathways worker Ready: Pathways Server serving on [::]:29001
RM(Resource Manager)已就绪,并且所有 TPU slice 最终均已就绪
Pathways Server serving on [::]:29001
...
...
***<num slices>/<num slices> Pathways Slices Now Ready ***
TPU 主机上的单个 Pathways worker 已就绪
Pathways Server serving on [::]:29001

Step 1: Metadata & Configuration Gathering

第 1 步:收集元数据和配置

Before initiating debugging, gather critical parameters to construct accurate queries: 1.
project
2.
cluster_name
3.
location
4. the workload name and kind (see Identifying the Workload) 5.
namespace
(default:
default
) 6.
issue_time
(UTC, when the failure was first noticed)
Always bound log queries in time. Use the window
[issue_time - 30m, issue_time + 30m]
, i.e. pass
--start_time="{start_time}" --duration=1h
to the debug_workload script, where
{start_time}
is
issue_time - 30m
in RFC 3339 (e.g.
2026-10-22T11:10:00Z
). Unbounded queries are slow and get truncated by
--limit
. Widen the window only if the first error is not in it.
  • If the window contains more than one failure, report each with timestamps and say which one matches the user's symptom.
  • Report the root cause and the workaround separately. The root cause is the component that logged the earliest stall or error (for example the proxy, the RM or a worker). A configuration change that avoids that code path (a different checkpoint handler, flag or topology) is a workaround or a contributing factor: list it under the fix, not as the root cause.
  • When you compare with other runs (an earlier attempt, a sibling test that passed, or the same test on other days), use the comparison to narrow down which code path is affected, not as proof of the cause. A setting that differs in a passing run does not explain the failure if a Pathways component logged the stall or error.
  • End the report with the checks you ran and their result, so the user can repeat them: preflight, the actions or
    gcloud logging read
    queries you used (with their time window), pod events, and node OOMs. Include checks that failed or could not run (e.g. no log access) and say what to run instead.
[!TIP]
Always check the recent chat context or shared log queries from the user. Often, all five fields can be directly scraped from their console links or queries!
开始调试前,请收集构建准确查询所需的关键参数:1.
project
2.
cluster_name
3.
location
4. 工作负载名称和类型(请参阅识别工作负载)5.
namespace
(默认值:
default
)6.
issue_time
(UTC,首次发现故障的时间)
始终为日志查询设置时间范围。使用窗口
[issue_time - 30m, issue_time + 30m]
,即向 debug_workload 脚本传递
--start_time="{start_time}" --duration=1h
,其中
{start_time}
是采用 RFC 3339 格式的
issue_time - 30m
(例如
2026-10-22T11:10:00Z
)。 无时间范围的查询速度较慢,并且会被
--limit
截断。仅当窗口内未找到首个错误时才扩大窗口。
  • 如果窗口内包含多个故障,请分别报告并附上时间戳,同时说明哪个故障与用户的症状相符。
  • 请分别报告根因和规避方法。根因是记录最早停滞或错误的组件,例如 proxy、RM 或 worker。能够避开该代码路径的配置更改(不同的 checkpoint handler、flag 或 topology)属于规避方法或促成因素:应将其列在修复方法中,而不是作为根因。
  • 当与其他运行实例进行比较时(更早的尝试、某个成功通过的并行测试,或其他日期运行的同一测试),应使用比较结果缩小受影响的代码路径范围,而不能将其视为原因的证明。如果某个 Pathways 组件已记录停滞或错误,则成功运行中不同的设置并不能解释故障。
  • 报告最后应列出你执行的检查及其结果,以便用户可以复现:预检、使用的操作或
    gcloud logging read
    查询(包含时间窗口)、Pod 事件和节点 OOM。对于失败或无法运行的检查(例如没有日志访问权限),也应列出,并说明应改为运行什么。
[!TIP]
始终检查用户最近的聊天上下文或共享日志查询。 通常,这五个字段都可以直接从其控制台链接或 查询中提取!

Identifying the Workload

识别工作负载

The debug_workload script finds the workload's logs by the object that created its pods. Use the matching flag (the examples in this skill use
--jobset_name
):
Workload kindFlagFind it with
JobSet (most training workloads, XPK)
--jobset_name=<name>
kubectl get jobsets -n {namespace}
LeaderWorkerSet (e.g. Pathways inference)
--lws_name=<name>
kubectl get leaderworkersets -n {namespace}
Plain Job (not created by a JobSet)
--job_name=<name>
kubectl get jobs -n {namespace} -l '!jobset.sigs.k8s.io/jobset-name'
Anything else (bare pods, custom controllers)
--pod_prefix=<prefix>
kubectl get pods -n {namespace}
For past incidents, list the pods that logged in the window and their owner labels instead:
bash
gcloud logging read 'resource.type="k8s_container"
  resource.labels.cluster_name="{cluster_name}"
  resource.labels.namespace_name="{namespace}"
  timestamp>="{start_time}" timestamp<="{end_time}"' \
  --project="{project}" --limit=10000 \
  --format='value(resource.labels.pod_name,labels."k8s-pod/jobset_sigs_k8s_io/jobset-name",labels."k8s-pod/leaderworkerset_sigs_k8s_io/name",labels."k8s-pod/batch_kubernetes_io/job-name")' \
  | sort -u
If parts of the workload run in different objects, query them together by repeating
--workload=<kind>:<name>
(kinds:
jobset
,
lws
,
job
,
pod
). For example, if the JAX client or the proxy runs in its own Job next to the Pathways JobSet, debug both:
--workload=jobset:{jobset_name} --workload=job:{client_job_name}
.
To see what else ran on the same nodes, run
scripts/debug_workload.py
with
--action=neighbors --execute
. It lists every namespace/pod/container that logged on the workload's nodes and marks the ones that are not part of the workload. Use it to spot another workload sharing the hosts (e.g. a second resource manager or proxy on the same host and port when host exclusivity is not set) and to find the real container names of the workload's pods (e.g. a custom-named colocated Python sidecar).
debug_workload 脚本通过创建 Pod 的对象查找工作负载日志。请使用匹配的 flag(此 skill 中的示例使用
--jobset_name
):
工作负载类型Flag查找方式
JobSet(大多数训练工作负载、XPK)
--jobset_name=<name>
kubectl get jobsets -n {namespace}
LeaderWorkerSet(例如 Pathways 推理)
--lws_name=<name>
kubectl get leaderworkersets -n {namespace}
普通 Job(并非由 JobSet 创建)
--job_name=<name>
kubectl get jobs -n {namespace} -l '!jobset.sigs.k8s.io/jobset-name'
其他类型(裸 Pod、自定义控制器)
--pod_prefix=<prefix>
kubectl get pods -n {namespace}
对于历史故障,请列出时间窗口内产生日志的 Pod 及其所有者标签,而不是:
bash
gcloud logging read 'resource.type="k8s_container"
  resource.labels.cluster_name="{cluster_name}"
  resource.labels.namespace_name="{namespace}"
  timestamp>="{start_time}" timestamp<="{end_time}"' \
  --project="{project}" --limit=10000 \
  --format='value(resource.labels.pod_name,labels."k8s-pod/jobset_sigs_k8s_io/jobset-name",labels."k8s-pod/leaderworkerset_sigs_k8s_io/name",labels."k8s-pod/batch_kubernetes_io/job-name")' \
  | sort -u
如果工作负载的不同部分运行在不同对象中,请通过重复
--workload=<kind>:<name>
(kind:
jobset
、
lws
、
job
、
pod
)将它们一起查询。 例如,如果 JAX client 或 proxy 作为独立 Job 与 Pathways JobSet 并行运行,请同时调试两者:
--workload=jobset:{jobset_name} --workload=job:{client_job_name}
。
要查看同一节点上还运行了什么,请运行
scripts/debug_workload.py
并指定
--action=neighbors --execute
。它会列出在工作负载节点上产生日志的每个 namespace/Pod/容器,并标记不属于该工作负载的对象。使用它可以发现共享同一主机的其他工作负载(例如未设置主机独占时,同一主机和端口上存在第二个 resource manager 或 proxy),以及查找工作负载 Pod 的真实容器名称(例如自定义命名的共置 Python sidecar)。

Retrieving Active YAML Configuration

获取当前 YAML 配置

If the workload is still active/alive, run the following command to inspect how it is structured and identify misconfigurations (use
leaderworkerset
or
job
instead of
jobset
for those kinds):
bash
kubectl get jobset {jobset_name} -n {namespace} -o yaml
If the workload has been deleted but you suspect misconfiguration, request the user to paste or share the workload YAML in the chat.
如果工作负载仍处于活动/存活状态,请运行以下命令检查其结构并识别配置错误(对于相应类型,请使用
leaderworkerset
或
job
,而不是
jobset
):
bash
kubectl get jobset {jobset_name} -n {namespace} -o yaml
如果工作负载已被删除,但你怀疑存在配置错误,请请用户在聊天中粘贴或分享工作负载 YAML。

Recording Versions

记录版本

Before reading errors, record each component's image tag (from the YAML or the pod spec) and
Build label
(logged at startup by pathways-rm, pathways-proxy and pathways-worker), plus the client's JAX, jaxlib and pathwaysutils versions. Check that they are from matching releases and that the flags passed to each component exist in its image.

读取错误之前,请记录每个组件的镜像标签(来自 YAML 或 Pod spec)和
Build label
(由 pathways-rm、pathways-proxy 和 pathways-worker 在启动时记录),以及客户端的 JAX、jaxlib 和 pathwaysutils 版本。 检查这些版本是否来自相互匹配的发行版本,并确认传递给每个组件的 flag 在其镜像中存在。

Step 1.5: Quick Triage - Preflight, Then Crash Sweep

第 1.5 步:快速分诊——先预检,再扫描崩溃

First run the preflight check. It verifies that you can read the project's logs and that the workload logged in the time window. An empty result from any other action is not a clean result until preflight passes. If you cannot run commands yourself (for example no log access) and give the user a plan or a list of commands instead, start that plan with the preflight command:
bash
python3 scripts/debug_workload.py \
  --project="{project}" \
  --cluster_name="{cluster_name}" \
  --location="{location}" \
  --jobset_name="{jobset_name}" \
  --start_time="{start_time}" --duration=1h \
  --action=preflight
Then, before reading containers one by one, run the crash and fatal-error sweep across all containers of the workload. It looks for segfaults,
Check failed
, Python tracebacks, OOM kills, unknown flags, permission errors, etc., and returns the earliest hits first:
bash
python3 scripts/debug_workload.py \
  --project="{project}" \
  --cluster_name="{cluster_name}" \
  --location="{location}" \
  --jobset_name="{jobset_name}" \
  --start_time="{start_time}" --duration=1h \
  --action=errors \
  --execute
The container of the earliest hit is usually where the root cause is; then use the container-specific playbook in Step 3 for that container. If the sweep is empty, also run
--action=node-ooms
(OOM kills often do not appear in container logs) and
--action=pod-events
.
If a cascade fills the output (hundreds of pods logging the same error), you may add
--first_per_pod=N
to keep only the first N matching log lines of each pod/container plus its last matching line, e.g.
--first_per_pod=1
to see which pod failed first and how the failure spread, or
--first_per_pod=3
to also see each pod's next few lines. Use it at your discretion: it fetches up to
--fetch_limit
lines (default 1000) before grouping, so it is slower than a plain query and can be slow or time out when the workload has many pods. Narrow the time window first, and prefer a plain query when only a few pods are involved. Never conclude "no crash" from a
--first_per_pod
sweep alone: it skips lines in the middle of each pod's log, and the fetch limit can cut off later pods. Confirm with a plain query on the suspect container.

首先运行预检检查。它会验证你能否读取项目日志,以及工作负载是否在时间窗口内产生了日志。在预检通过前,其他任何操作返回空结果都不能视为一切正常。如果你无法亲自运行命令(例如没有日志访问权限),而只能向用户提供计划或命令列表,请让该计划从预检命令开始:
bash
python3 scripts/debug_workload.py \
  --project="{project}" \
  --cluster_name="{cluster_name}" \
  --location="{location}" \
  --jobset_name="{jobset_name}" \
  --start_time="{start_time}" --duration=1h \
  --action=preflight
然后,在逐个读取容器之前,对工作负载的所有容器运行崩溃和致命错误扫描。它会查找 segfault、
Check failed
、Python traceback、OOM kill、未知 flag、权限错误等,并按最早命中时间排序返回结果:
bash
python3 scripts/debug_workload.py \
  --project="{project}" \
  --cluster_name="{cluster_name}" \
  --location="{location}" \
  --jobset_name="{jobset_name}" \
  --start_time="{start_time}" --duration=1h \
  --action=errors \
  --execute
最早命中的容器通常就是根因所在;随后对该容器使用第 3 步中的容器专用手册。如果扫描结果为空,还应运行
--action=node-ooms
(OOM kill 通常不会出现在容器日志中)和
--action=pod-events
。
如果级联错误淹没输出(数百个 Pod 记录同一错误),可以添加
--first_per_pod=N
,只保留每个 Pod/容器的前 N 条匹配日志及最后一条匹配日志。例如,使用
--first_per_pod=1
可以查看哪个 Pod 最先失败以及故障如何扩散,或使用
--first_per_pod=3
进一步查看每个 Pod 的后续几条日志。可以自行决定是否使用;该操作会先获取最多
--fetch_limit
行(默认 1000)再进行分组,因此比普通查询更慢,在工作负载包含大量 Pod 时可能很慢或超时。请先缩小时间窗口,且当仅涉及少量 Pod 时优先使用普通查询。绝不能仅凭
--first_per_pod
扫描就断定“没有崩溃”:它会跳过每个 Pod 日志中间的若干行,获取上限也可能截断后续 Pod 的日志。请使用针对可疑容器的普通查询进行确认。

Step 2: GKE JobSet Lifecycle Verification

第 2 步:验证 GKE JobSet 生命周期

If the workload has not started or failed immediately at scheduling time:
如果工作负载尚未启动,或在调度时立即失败:

1. Verify Webhook & Scheduling Status

1. 验证 Webhook 与调度状态

Identify if scheduling blocks are occurring due to insufficient cluster resources or webhook failures.
Check for webhook mutating errors,
OOMKilled
controller managers, or Unschedulable conditions:
bash
undefined
确定是否因集群资源不足或 Webhook 失败而发生调度阻塞。
检查 Webhook mutating error、
OOMKilled
controller manager 或 Unschedulable 状态:
bash
undefined

Check controller manager pods in the JobSet system namespace

Check controller manager pods in the JobSet system namespace

kubectl get pods -n jobset-system
undefined
kubectl get pods -n jobset-system
undefined

2. Symptom: Forever Suspended JobSet

2. 症状:JobSet 永久挂起

If a JobSet is created but remains in a permanently
Suspended
state and never spawns child pods:
  • Potential Root Causes:
    • The JobSet name is too long. Because JobSet appends replicated job names and index numbers to child resources, long prefixes fail standard Kubernetes resource name validation (max 63/253 chars).
    • The JobSet YAML is malformed (e.g. invalid or missing fields, wrong resource requests or node selectors), so the workload is never admitted to the queue and stays suspended. Ask the user for the YAML (see Retrieving Active YAML Configuration) and check it for errors.
  • Diagnosis: Check the JobSet controller manager logs in
    jobset-system
    namespace to find truncation, length limit, name-generation, or validation errors. You can use the debug_workload script to quickly query the logs:
bash
python3 scripts/debug_workload.py \
  --project="{project}" \
  --cluster_name="{cluster_name}" \
  --location="{location}" \
  --jobset_name="{jobset_name}" \
  --start_time="{start_time}" --duration=1h \
  --action=summary \
  --execute
如果 JobSet 已创建,但始终处于永久
Suspended
状态且从未生成子 Pod:
  • 潜在根因:
    • JobSet 名称过长。由于 JobSet 会将复制的 Job 名称和索引编号附加到子资源名称中,较长的前缀无法通过标准 Kubernetes 资源名称验证(最大 63/253 个字符)。
    • JobSet YAML 格式错误,例如字段无效或缺失、资源请求或 node selector 不正确,导致工作负载始终无法进入队列并保持挂起。请用户提供 YAML(请参阅获取当前 YAML 配置),并检查其中是否存在错误。
  • 诊断:检查
    jobset-system
    namespace 中的 JobSet controller manager 日志,查找名称截断、长度限制、名称生成或验证错误。可以使用 debug_workload 脚本快速查询日志:
bash
python3 scripts/debug_workload.py \
  --project="{project}" \
  --cluster_name="{cluster_name}" \
  --location="{location}" \
  --jobset_name="{jobset_name}" \
  --start_time="{start_time}" --duration=1h \
  --action=summary \
  --execute

3. SIGTERM and Pre-emption Diagnosis

3. SIGTERM 与抢占诊断

  • SIGTERMs are the most common mechanism for GKE to stop/restart workloads. A SIGTERM is a symptom; find out who sent it.
  • Common senders: Spot VM preemption, Compute Engine host maintenance, host errors, node auto-repair, or a JobSet restart triggered by another failed container. Check infrastructure interruptions and pod events for the time window:
    bash
    python3 scripts/debug_workload.py \
      --project="{project}" \
      --cluster_name="{cluster_name}" \
      --location="{location}" \
      --jobset_name="{jobset_name}" \
      --start_time="{start_time}" --duration=1h \
      --action=interruptions \
      --execute
    # then the same command with --action=pod-events
  • If no infrastructure event explains the SIGTERM, trace the failure back from the user workload to the TPU that failed first:
    1. In the user workload logs (
      --action=user-workload
      ), find the time of the first error or the last completed step.
    2. In the RM logs (
      --action=pathways-rm
      ) around that time, find when the first failure occurred or the first TPU slice/worker stopped responding (e.g. a slice leaving the ready state or
      Job cancelled due to ...
      ), and which slice/worker it was.
    3. Inspect that worker's logs (
      --action=workers
      , adding
      --min_severity=WARNING
      if needed) and its node's events (
      --action=pod-events
      ,
      --action=node-ooms
      ,
      --action=interruptions
      ) to find out what happened there.
    4. The cause can be a user code error (unlikely) or another fault, such as a hardware failure, an OOM, a crash in the worker, or a node interruption.
  • kubectl get events -n {namespace} --field-selector involvedObject.name={jobset_name}
    only works for live incidents: Kubernetes keeps events for a certain time only. For past incidents use
    --action=pod-events
    /
    --action=summary
    , which read the events from Cloud Logging.
  • For deeper analysis of restarts and interruptions, follow the public gke-ai-troubleshooting-jobset-interruption skill; for host maintenance, follow gke-ai-troubleshooting-handle-disruption-gpu-tpu.

  • SIGTERM 是 GKE 停止或重启工作负载最常见的机制。SIGTERM 只是症状;应找出是谁发送了该信号。
  • 常见发送方包括 Spot VM 抢占、Compute Engine 主机维护、主机错误、节点自动修复,或由另一个失败容器触发的 JobSet 重启。请检查时间窗口内的基础设施中断和 Pod 事件:
    bash
    python3 scripts/debug_workload.py \
      --project="{project}" \
      --cluster_name="{cluster_name}" \
      --location="{location}" \
      --jobset_name="{jobset_name}" \
      --start_time="{start_time}" --duration=1h \
      --action=interruptions \
      --execute
    # then the same command with --action=pod-events
  • 如果没有基础设施事件可以解释 SIGTERM,请从用户工作负载向前追踪到最先失败的 TPU:
    1. 在用户工作负载日志(
      --action=user-workload
      )中,找到首个错误的时间或最后完成的步骤。
    2. 在 RM 日志(
      --action=pathways-rm
      )中查找该时间附近首次发生的故障,或首次停止响应的 TPU slice/worker(例如 slice 离开 ready 状态,或出现
      Job cancelled due to ...
      ),并确定具体是哪个 slice/worker。
    3. 检查该 worker 的日志(
      --action=workers
      ,必要时添加
      --min_severity=WARNING
      )及其节点事件(
      --action=pod-events
      、
      --action=node-ooms
      、
      --action=interruptions
      ),查明发生了什么。
    4. 原因可能是用户代码错误(可能性较低),也可能是硬件故障、OOM、worker 崩溃或节点中断等其他故障。
  • kubectl get events -n {namespace} --field-selector involvedObject.name={jobset_name}
    仅适用于正在发生的故障:Kubernetes 只会在有限时间内保留事件。对于历史故障,请使用
    --action=pod-events
    或
    --action=summary
    ,它们会从 Cloud Logging 读取事件。
  • 如需进一步分析重启和中断,请参阅公开的 gke-ai-troubleshooting-jobset-interruption skill;如需处理主机维护,请参阅 gke-ai-troubleshooting-handle-disruption-gpu-tpu。

Step 3: Container-Specific Debugging Playbook

第 3 步:容器专用调试手册

Because Pathways is distributed, inspect logs container-by-container in logical order to avoid cascade noise, and always chase the earliest error. Before you query a container, read its section in Container Playbooks: it has the log signals, the
debug_workload.py
command and the gotchas for that container.
OrderContainerActionLook forPlaybook
1User workload (
user-workload
,
main
,
jax-tpu
)
--action=user-workload
The last completed step, then the first exceptionA
2IFRT proxy
--action=proxy
Connection refused
to the RM port (
:29001
),
Socket closed
B
3Resource manager (
pathways-rm
)
--action=pathways-rm
Slice ready transitions, placement, a repeated
Build label
(restarts)
C
4Pathways workers (
pathways-worker
)
--action=workers
The first worker that failed, Megascale stall detectors (
HANG_DETECTED
)
D
5Colocated Python sidecar
--action=colocated-python-sidecar
Workers waiting for a sidecar that diedE
Rules that apply to every container:
  • A client-side
    Unable to initialize backend 'proxy': UNAVAILABLE: Unable to establish connection
    is a symptom. Check whether the proxy, RM and workers started (see Parsing Important Logs) and find their earliest error before you suspect the user's code.
  • IFRT proxy server was terminated: UNAVAILABLE: Socket closed
    and
    SLICE_FAILURE_CHIP_DRIVER_ERROR
    are downstream errors: go to the RM and worker logs.
  • When one worker fails, the other workers of the slice fail shortly after. The root cause is in the logs of the first worker that failed.
  • The built-in search terms only cover known failures. If an action returns nothing useful, re-run it with
    --min_severity=WARNING
    (
    DEFAULT
    for the user workload) and add the workload's own strings with
    --extra_terms
    .
  • If the logs still don't explain the failure, read all logs of the container (F), then ask for more verbose proxy logs or XProfs (G).

由于 Pathways 是分布式系统,请按照合理的顺序逐个检查容器日志,以避免级联错误造成干扰,并且始终追踪最早出现的错误。查询容器之前,请阅读 容器调试手册中的对应章节:其中包含该容器的日志信号、
debug_workload.py
命令和注意事项。
顺序容器操作查找内容手册
1用户工作负载(
user-workload
、
main
、
jax-tpu
)
--action=user-workload
最后完成的步骤,以及首个异常A
2IFRT proxy
--action=proxy
到 RM 端口(
:29001
)的
Connection refused
、
Socket closed
B
3Resource manager(
pathways-rm
)
--action=pathways-rm
Slice ready 状态转换、放置情况、重复出现的
Build label
(重启)
C
4Pathways workers(
pathways-worker
)
--action=workers
首个失败的 worker、Megascale 停滞检测器(
HANG_DETECTED
)
D
5共置 Python sidecar
--action=colocated-python-sidecar
Worker 等待一个已经退出的 sidecarE
适用于所有容器的规则:
  • 客户端出现
    Unable to initialize backend 'proxy': UNAVAILABLE: Unable to establish connection
    是症状。检查 proxy、RM 和 worker 是否已启动(请参阅解析重要日志),并找到它们最早出现的错误,之后再怀疑是用户代码问题。
  • IFRT proxy server was terminated: UNAVAILABLE: Socket closed
    和
    SLICE_FAILURE_CHIP_DRIVER_ERROR
    是下游错误:请查看 RM 和 worker 日志。
  • 当一个 worker 失败时,同一 slice 中的其他 worker 很快也会失败。 根因位于首个失败 worker 的日志中。
  • 内置搜索词仅覆盖已知故障。如果某项操作未返回有用结果,请使用
    --min_severity=WARNING
    重新运行(用户工作负载使用
    DEFAULT
    ),并通过
    --extra_terms
    添加工作负载自身的字符串。
  • 如果日志仍无法解释故障,请读取该容器的所有日志(F),然后请用户提供更详细的 proxy 日志或 XProfs(G)。

Step 4: Special Scenarios

第 4 步:特殊场景

These known failures have a specific cause and fix. When an error or symptom matches a row, read that scenario in Special Scenarios before you conclude:
Error or symptomScenario
JaxRuntimeError
with
DATA_LOSS
during scale changes; elastic recovery or checkpoint restore fails
1. Elastic training and checkpoint restore
Container restarts or exit code 137 without
OOMKilled
;
Memory cgroup out of memory
,
oom-kill
,
OOMKilling
2. Host OOM kills on the head pod or TPU hosts
Unable to initialize backend 'proxy': Backend 'proxy' is not in the list of known backends
3. Backend proxy is not in the list of known backends
SIGTERM received by PID 1
; containers stop without a clear error
4. SIGTERM received by PID 1
FAILED_PRECONDITION: The newly added instance does not match with the expected instances
5. Newly added instance does not match the expected instances
Connection to IFRT proxy server was terminated: FAILED_PRECONDITION: GrpcClientSession: writes no longer allowed
6. Connection to the IFRT proxy server was terminated
XlaRuntimeError: ABORTED: ... The metadata for object was edited during the operation
7. Cached executable metadata was edited during the operation
DEADLINE_EXCEEDED: lost connection to peer
or
DATA_LOSS: Pipe from scheduler to aggregator
8. Lost connection to peer
Status 11 from handshaker service: Input frame length is out of range
9. ALTS handshake error from a client outside Google Cloud
Lifecycle matches_prefix cannot specify more than 50 prefixes per config
10. Cloud Storage lifecycle prefix limit
IFRT Proxy client and server failed to agree on the protocol version
, or
Failed to deserialize the Mosaic module: ... Unsupported version
11. JAX and Pathways version mismatch: compare the client's JAX, jaxlib and pathwaysutils versions with the Pathways image tags and
Build label
s
Pods in
ImagePullBackOff
or
ErrImagePull
12. Pods stuck in ImagePullBackOff or ErrImagePull: read the pull error in the pod events, then list the registry's tags (
gcloud artifacts docker tags list
)
Address already in use
,
Init:Error
, or
didn't have free ports
13. Port collisions with hostNetwork
No error anywhere, but the job stops making progress14. The job hangs without failing
Still waiting to acquire semaphore
,
Recv completion error
,
GOAWAY
15. Proxy-to-worker transfers stall

这些已知故障具有特定原因和修复方法。当错误或症状与某一行匹配时,请在得出结论前阅读 特殊场景中的对应场景:
错误或症状场景
扩缩容期间出现带
DATA_LOSS
的
JaxRuntimeError
;弹性恢复或 checkpoint 恢复失败
1. 弹性训练和 checkpoint 恢复
容器重启或退出码为 137,但没有
OOMKilled
;出现
Memory cgroup out of memory
、
oom-kill
、
OOMKilling
2. Head Pod 或 TPU 主机上的 Host OOM Kill
Unable to initialize backend 'proxy': Backend 'proxy' is not in the list of known backends
3. 后端 proxy 不在已知后端列表中
SIGTERM received by PID 1
;容器停止且没有明确错误
4. PID 1 收到 SIGTERM
FAILED_PRECONDITION: The newly added instance does not match with the expected instances
5. 新增实例与预期实例不匹配
Connection to IFRT proxy server was terminated: FAILED_PRECONDITION: GrpcClientSession: writes no longer allowed
6. 到 IFRT proxy server 的连接被终止
XlaRuntimeError: ABORTED: ... The metadata for object was edited during the operation
7. 操作期间缓存的 executable metadata 被修改
DEADLINE_EXCEEDED: lost connection to peer
或
DATA_LOSS: Pipe from scheduler to aggregator
8. 与对等端失去连接
Status 11 from handshaker service: Input frame length is out of range
9. 来自 Google Cloud 外部客户端的 ALTS 握手错误
Lifecycle matches_prefix cannot specify more than 50 prefixes per config
10. Cloud Storage lifecycle prefix 限制
IFRT Proxy client and server failed to agree on the protocol version
,或
Failed to deserialize the Mosaic module: ... Unsupported version
11. JAX 与 Pathways 版本不匹配:将客户端的 JAX、jaxlib 和 pathwaysutils 版本与 Pathways 镜像标签及
Build label
进行比较
Pod 处于
ImagePullBackOff
或
ErrImagePull
状态
12. Pod 卡在 ImagePullBackOff 或 ErrImagePull 状态:从 Pod 事件中读取拉取错误,然后列出 registry 的标签(
gcloud artifacts docker tags list
)
Address already in use
、
Init:Error
或
didn't have free ports
13. hostNetwork 端口冲突
任何位置都没有错误,但 Job 停止推进14. Job 未失败却陷入卡住状态
Still waiting to acquire semaphore
、
Recv completion error
、
GOAWAY
15. Proxy 到 worker 的传输停滞

Related Public Skills and Writing Your Own Queries

相关公开 Skills 与自定义查询

These public skills from github.com/google/skills complement this skill. If they are installed, use them by name; otherwise read them from the links.
SymptomPublic skill
Writing a custom Cloud Logging querycloud-logging-query-generation (GKE examples: query_gke.md)
JobSet restarts, Spot preemption, maintenance, host terminationgke-ai-troubleshooting-jobset-interruption
Compute Engine host maintenance on TPU/GPU nodesgke-ai-troubleshooting-handle-disruption-gpu-tpu
Multi-slice job stops responding (
HANG_DETECTED
)
gke-ai-troubleshooting-tpu-mxla-hang
Node NotReady, unresponsive node, auto-repairgke-ai-troubleshooting-node-unresponsive-timeout
When you write your own queries:
  • Always use double quotes for strings, uppercase
    AND
    /
    OR
    /
    NOT
    , and parentheses to group terms.
  • Restrict
    resource.type
    (
    k8s_container
    ,
    k8s_pod
    ,
    k8s_node
    ,
    gke_nodepool
    ,
    gce_instance
    ) and use
    log_id("events")
    ,
    log_id("stdout")
    or
    log_id("stderr")
    where possible.
  • Always add a time window (
    timestamp>="..."
    and
    timestamp<="..."
    ).
  • Pathways components log glog lines into
    jsonPayload.message
    (some containers) or
    textPayload
    (others); bare quoted terms or
    SEARCH()
    match both.
  • Pod label keys are stored with
    .
    replaced by
    _
    , e.g.
    labels."k8s-pod/batch_kubernetes_io/job-completion-index"
    and
    labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"
    . Some public examples spell the Job label with dots (
    batch.kubernetes.io/job-name
    ); that form does not match Pathways logs.
以下来自 github.com/google/skills 的公开 skills 可以作为本 skill 的补充。如果已经安装,请按名称使用;否则请通过链接阅读。
症状公开 skill
编写自定义 Cloud Logging 查询cloud-logging-query-generation(GKE 示例:query_gke.md)
JobSet 重启、Spot 抢占、维护、主机终止gke-ai-troubleshooting-jobset-interruption
TPU/GPU 节点上的 Compute Engine 主机维护gke-ai-troubleshooting-handle-disruption-gpu-tpu
多 slice Job 停止响应(
HANG_DETECTED
)
gke-ai-troubleshooting-tpu-mxla-hang
Node NotReady、节点无响应、自动修复gke-ai-troubleshooting-node-unresponsive-timeout
编写自己的查询时:
  • 字符串始终使用双引号,使用大写的
    AND
    /
    OR
    /
    NOT
    ,并使用括号对条件进行分组。
  • 限制
    resource.type
    (
    k8s_container
    、
    k8s_pod
    、
    k8s_node
    、
    gke_nodepool
    、
    gce_instance
    ),并尽可能使用
    log_id("events")
    、
    log_id("stdout")
    或
    log_id("stderr")
    。
  • 始终添加时间窗口(
    timestamp>="..."
    和
    timestamp<="..."
    )。
  • Pathways 组件会将 glog 行记录到
    jsonPayload.message
    (部分容器)或
    textPayload
    (其他容器)中;不带字段名的带引号词项或
    SEARCH()
    可同时匹配两者。
  • Pod 标签键存储时会把
    .
    替换为
    _
    ,例如
    labels."k8s-pod/batch_kubernetes_io/job-completion-index"
    和
    labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"
    。一些公开示例使用带点的 Job 标签写法(
    batch.kubernetes.io/job-name
    );这种写法与 Pathways 日志不匹配。