环境变量
本页所有地址都适用于
libtpu-0.0.40-cp314wheel 中的libtpu.so(构建libtpu_lts_20260413_b_RC00,build-id md589edbbe81c5b328a958fe628a9f2207d,781,691,048 字节,ELF x86-64 DYN,未 strip;反混淆后的 C++ 符号按原样引用)。其他版本会不同。
摘要
libtpu 从两个来源读取配置;从 shell 看它们相似,但在 .so 内部接线完全不同。第一个来源是一小组固定环境变量,TPU 代码通过 getenv("LITERAL_NAME") 直接读取它们。这些变量是重新实现者必须硬编码的,因为名称字符串被烘入某个具体 reader 函数,背后没有注册表。第二个也是大得多的表面,是 absl/XLA flag 机制:XLA_FLAGS、TF_XLA_FLAGS,以及通过 LIBTPU_INIT_ARGS 注入的 --xla_* / --tpu_* flag 根本不是由 getenv 读取的,而是在 bootstrap 时由 ParseCommandLineNonHelpFlags 针对 dlopen 构造函数风暴预先注册的 absl flag 表解析一次。本页负责维护 直接 getenv 目录:二进制传给 getenv 的每个字面 env-var 名称、读取它的函数,以及该值的作用。flag 表面及其注入通道在别处说明(见交叉引用)。
对重新实现者来说,关键事实是两者之间的分界线。对 .rodata 做 grep 会找到数百个 TPU_*、MEGASCALE_*、GRPC_* 和 TF_* 字符串,但大多数都不是 env-var 读取:TPU_CORE_TYPE_*、TPU_SEQUENCER_TYPE_* 等类似字符串是枚举名;TPU_VISIBLE_DEVICES、TPU_HOST_BOUNDS 和 TPU_SKIP_MDS_QUERY 是 absl flag 名称,由 flag parser 绑定,而不是由 getenv 绑定;MEGASCALE_* 和 GRPC_* 家族分别是分布式运行时层和 gRPC 层消费的 flag/option 字符串。在反编译语料中,只有约 205 个不同字符串会到达字面 getenv();其中只有少数是 TPU 专属的,其余继承自 vendored 库(hwloc、libpfm、gRPC、GCS、Google base/ init runtime、absl test harness)。下面的目录把 TPU 拥有的直接读取(CONFIRMED reader + 地址)和 flag 绑定名称(CONFIRMED 字符串,解析但不 getenv)分开,让重新实现者知道哪些要实现为 getenv,哪些要实现为 flag。
关于 secure_getenv 的说明:尽管运行时其他位置有分派加固,反编译语料中没有保留下任何字面参数 secure_getenv("NAME") 调用,每个已确认的 env 读取都是普通 getenv。bootstrap 在解析环境时已经不是以提升权限运行,因此运行时不会为了 setuid 上下文而放弃 env 访问。
| Flag 注入通道 | LIBTPU_INIT_ARGS → GetLibTpuInitArguments @ 0x20ccca20 (851 B) |
| 锁 + 拓扑 gate reader | tensorflow::tpu::TryAcquireTpuLock @ 0x20ccbc40 (3531 B) |
| TfRT 运行时选择器 | tpu::ShouldUseTfrt @ 0x1d0fc740(lambda $_0 @ 0x1d0fc800 中的 getenv)读取 ENABLE_TFRT_TPU_RUNTIME |
| Megascale gate | PJRT_Client_Create @ 0xe6a8840 读取 SKIP_MEGASCALE_PJRT_CLIENT |
| Uptime 遥测 reader | InitializeUptimeMetricViaEnvironmentVariables @ 0x20a65720 读取 TPU_ML_PLATFORM[_VERSION] |
| 预映射缓冲区 reader | TpuStatesManager::GetOrCreateTpuSystemState @ 0xf956e40 |
XLA_FLAGS / TF_XLA_FLAGS | 不是由 getenv 读取,而是由 absl/tsl 的从环境读取 flag 机制解析 |
TPU_LIBRARY_PATH | 由 wheel 的 __init__.py 设置,由框架 loader 读取,不由 libtpu 读取 |
不同的字面 getenv 参数(整个 .so) | ~205(多数来自 vendored:hwloc、libpfm、gRPC、GCS、Google base) |
secure_getenv 字面参数站点 | 未观察到 |
| 置信度 | CONFIRMED = 在所引地址的反编译 reader 中有字面 getenv("NAME") |
如何阅读本目录
每一行都带有一个 Reader(消费该变量的函数和地址)以及一个 Confidence,在这里它具有特定含义:
- CONFIRMED — 二进制在所引函数内包含字面
getenv("NAME")(或 flag 绑定行中的 flag 字符串)。重新实现者应精确复现这一点。 - HIGH — env-var 字符串存在,并且已识别出消费它的子系统,但精确 reader 调用是从周围函数推断出来的,而不是钉到某一行
getenv。 - LOW — 字符串存在,但它是否被读取(而不是被定义为 flag 名称、枚举名,或写入日志的值)尚未解析。
陷阱 —
.rodata中的字符串并不能证明存在 env-var 读取。这里最常见的重新实现错误,是把 absl flag 名称(例如TPU_VISIBLE_DEVICES)当成getenv目标。libtpu 通过 flag parser 绑定这些名称;在重新实现中调用getenv("TPU_VISIBLE_DEVICES")会读取一个 libtpu 从不读取的变量。目录会明确标记每个 flag 绑定名称。
1. Flag 注入
这是主要配置通道。插件 .so 没有自己的命令行,所以 libtpu 从 LIBTPU_INIT_ARGS 伪造一个命令行,并把它喂给 absl flag parser。摄取的机制——按空格拆分、合成 argv[0]、将 vector<string> → char** 展平——在 ../lifecycle/tftpu-initialize-bootstrap.md §2 中完整记录;该字符串携带的 flag 在 xla-flag-atlas.md 中编目。本页只记录 env-var 读取本身。
| Variable | Reader(symbol @ addr) | Effect | Default |
|---|---|---|---|
LIBTPU_INIT_ARGS | tensorflow::tpu::GetLibTpuInitArguments @ 0x20ccca20 | 由字面 getenv 读取;该值按空格(ASCII 0x20)拆分为一个 vector<string> 和一个并行的 vector<char const*> argv,并由函数返回。argv[0] 合成、Cloud-TPU 默认值前置,以及 ParseCommandLineNonHelpFlags 调用发生在 bootstrap 调用者中,而不是此函数中。它是每个 --xla_* / --tpu_* flag 的注入点。 | 未设置 → 空 argv(无注入 flag) |
XLA_FLAGS | absl/tsl ParseFlagsFromEnvAndDieIfUnknown(字符串 @ .rodata,TPU 代码不对它调用 getenv) | 标准 XLA 从环境读取 flag 的通道;与 LIBTPU_INIT_ARGS argv 合并到同一组 absl flag 表。 | 未设置 → 无 env flag |
TF_XLA_FLAGS | xla::ParseFlagsFromEnvAndDieIfUnknown("TF_XLA_FLAGS", …)(在 AllocateAndParseFlags @ 0xfe5fe80 中,不由 getenv 读取) | TensorFlow-bridge XLA flag 通道;同一组 flag 表。 | 未设置 |
注意 —
LIBTPU_INIT_ARGS是本组中唯一由字面getenv读取的 TPU 专属变量。XLA_FLAGS/TF_XLA_FLAGS由通用 absl 从环境读取 flag 的代码读取(absl::ParseCommandLine通过类似ABSL_FLAGS_FROM_ENV的扫描读取它们),因此它们在效果上是环境变量,但不是在任何 TPU 调用点被getenv读取。重新实现者必须把三者都接到一次 flag parse 中,但只有LIBTPU_INIT_ARGS是 TPU 层手写的getenv。
2. 设备选择和拓扑
这些变量描述进程应看到的 slice 几何。这里的拆分非常明确,也很容易弄错:bounds 变量在锁 gate 内部由 getenv 直接读取,而 visible-device 选择器是 absl flag 名称。
直接 getenv 读取
| Variable | Reader(symbol @ addr) | Effect | Default |
|---|---|---|---|
TPU_CHIPS_PER_HOST_BOUNDS | tensorflow::tpu::TryAcquireTpuLock @ 0x20ccbc40 | 每主机 chip 网格(x,y,z),用于计算设备锁和本地拓扑占用。与锁获取一起读取。 | 未设置 → 从检测到的硬件派生 |
TPU_CHIPS_PER_PROCESS_BOUNDS | tensorflow::tpu::TryAcquireTpuLock @ 0x20ccbc40 | 每进程 chip 网格;限制此进程声明的 chip,在每主机多进程布局中缩小 host bounds。 | 未设置 → 等于 host bounds |
ALLOW_MULTIPLE_LIBTPU_LOAD | tensorflow::tpu::TryAcquireTpuLock @ 0x20ccbc40 | 设置后,放宽单 loader 跨进程锁,使多个 libtpu 实例可以绑定设备。 | 未设置 → 强制单次加载 |
TPU_LOAD_LIBRARY | tensorflow::tpu::TryAcquireTpuLock @ 0x20ccbc40 | 控制是否甚至尝试获取跨进程 TPU 锁(见 ../lifecycle/tftpu-initialize-bootstrap.md §5)。 | 未设置 → 尝试获取锁 |
Flag 绑定名称(不由 getenv 读取)
| Name | Where bound | Effect |
|---|---|---|
TPU_VISIBLE_DEVICES | absl flag table | 逗号分隔的设备索引 allow-list;由设备枚举器通过 flag parser 消费,而不是 getenv。 |
TPU_VISIBLE_CHIPS | absl flag table | chip 级可见性 allow-list(与 TPU_VISIBLE_DEVICES 并存的较新拼写)。 |
TPU_VISIBLE_DEVICE_PATHS | absl flag table | 要绑定的显式设备节点路径。 |
TPU_HOST_BOUNDS | absl flag table | Host 网格(x,y,z)——这是 flag 形式,不同于由 getenv 读取的 TPU_CHIPS_PER_HOST_BOUNDS。 |
TPU_SKIP_MDS_QUERY | absl flag table | 跳过 metadata-server 拓扑查询,强制依赖本地提供的 bounds/topology。 |
TPU_TOPOLOGY_WRAP / TPU_TOPOLOGY_ALT | absl flag table | slice 几何的 torus wrap 模式 / 备用拓扑选择器。 |
TPU_MEGACORE | absl flag table | 对应 chip 代际的 megacore 配对模式。 |
TPU_ACCELERATOR_TYPE | absl flag table | 加速器类型标签(例如 v5e-4),由 PJRT 拓扑名称表映射到拓扑。 |
怪癖 — 存在两个 host-bounds 旋钮,接线不同。
TPU_CHIPS_PER_HOST_BOUNDS是TryAcquireTpuLock内部真实的getenv读取;TPU_HOST_BOUNDS是由 absl 解析的 flag 名称。它们含义重叠,但通过不同路径进入运行时——重新实现者必须把前者复现为getenv,把后者复现为 flag,否则二者之一会悄悄不起作用。
3. 运行时模式和缓冲区调优
选择运行时后端并调优传输缓冲区的直接 getenv 读取。
| Variable | Reader(symbol @ addr) | Effect | Default |
|---|---|---|---|
ENABLE_TFRT_TPU_RUNTIME | tpu::ShouldUseTfrt @ 0x1d0fc800(lambda $_0) | 选择基于 TfRT 的 TPU 运行时路径,而不是旧版 StreamExecutor 路径。由 ShouldUseTfrt 谓词读取一次。 | 未设置 → 后端默认值 |
SKIP_MEGASCALE_PJRT_CLIENT | pjrt::tpu_plugin::PJRT_Client_Create @ 0xe6a8840 | 设置后,PJRT_Client_Create(PJRT slot 15)跳过把 client 包装成 Megascale multi-slice client,直接返回 single-slice client。 | 未设置 → 存在 multi-slice 配置时构建 Megascale client |
TPU_PREMAPPED_BUFFER_SIZE | xla::TpuStatesManager::GetOrCreateTpuSystemState @ 0xf956e40 | 每个 TPU system 预留的预映射 DMA staging buffer 大小(字节)。 | 未设置 → 运行时选择的大小 |
TPU_PREMAPPED_BUFFER_TRANSFER_THRESHOLD_BYTES | xla::TpuStatesManager::GetOrCreateTpuSystemState @ 0xf956e40 | 传输大小阈值;超过该阈值时使用预映射 buffer 路径,而不是每次传输单独 mapping。 | 未设置 → 运行时默认阈值 |
DISABLE_HOST_SEND_RECV_REGISTRATION | _GLOBAL__sub_I_sendrecv_ops.cc @ 0x212c9af0(static ctor) | 在模块初始化时抑制 host 侧 send/recv op 的注册。在 dlopen 构造函数风暴期间由 file-static 构造函数读取。 | 未设置 → 注册 host send/recv |
PJRT_NPROC | xla::DefaultThreadPoolSize @ 0x1d7f4800 | 用于确定默认线程池大小的进程数;未设置时回退到 NPROC。由字面 getenv 读取。 | 未设置 → 回退到 NPROC,再派生大小 |
CLOUD_TPU_TASK_ID | tpu::TpuHal::GetTaskId @ 0x1e8142c0 | 此进程在 Cloud-TPU job 内的 task index;multi-host job 需要它(如果需要但缺失,reader 会报错 "'CLOUD_TPU_TASK_ID' not specified for a multi-host job.")。由字面 getenv 读取。 | 未设置 → single-host / 派生 |
4. 分布式 / Megascale 和协调
multi-slice(Megascale)层几乎完全由 flag 绑定的 MEGASCALE_* 字符串配置,而不是由 getenv 配置。Megascale 路径中唯一的直接 getenv 是 §3 中的旁路开关(SKIP_MEGASCALE_PJRT_CLIENT)。消费这些配置的协调/拓扑交换记录在 ../megascale/bootstrap/overview.md 中。
| Name | Consumer | Effect |
|---|---|---|
MEGASCALE_COORDINATOR_ADDRESS | Megascale bootstrap(flag/option) | 用于跨 slice rendezvous 和 coordinator election 的协调服务地址。 |
MEGASCALE_NUM_SLICES | Megascale bootstrap | multi-slice job 中的总 slice 数;驱动 barrier 和 topology-exchange 的大小。 |
MEGASCALE_SLICE_ID | Megascale bootstrap | 此进程的 slice index。 |
MEGASCALE_PORT / MEGASCALE_DEBUG_PORT | Megascale transport | inter-slice transport 的 service / debug 监听端口。 |
MEGASCALE_TRANSPORT_TYPE | Megascale transport | 选择 cross-slice transport(例如 gRPC vs. DCN)。 |
MEGASCALE_TOPOLOGY | Megascale bootstrap | multi-slice topology descriptor。 |
MEGASCALE_AUTHENTICATION | Megascale transport | coordination channel 的认证模式。 |
MEGASCALE_TRACING / MEGASCALE_GRPC_ENABLE_XOR_TRACER | Megascale tracing | 启用 Megascale request tracing / gRPC XOR tracer。 |
TPU_WORKER_ID | distributed init(flag/string) | distributed TPU job 内的 worker index。 |
TPU_WORKER_HOSTNAMES | distributed init(flag/string) | 该 job 的逗号分隔 worker hostnames。 |
TF_TASK_ID / TF_JOB_NAME | getenv(TF distributed identity) | TensorFlow distributed setup 中的 task index / job name。由字面 getenv 读取。 |
注意 —
MEGASCALE_*家族由 multi-slice runtime 通过其 options/flag parsing 消费,而不是通过离散getenv调用消费;因此尽管所有十个字符串都出现在.rodata中,它们并不出现在字面getenv集合里。旁路(SKIP_MEGASCALE_PJRT_CLIENT)是例外:它是PJRT_Client_Create内部真实的getenv,因为它必须在任何 Megascale option parsing 发生之前短路。
5. Profiling、Dump 和遥测
这里混合了直接 getenv 读取(遥测平台标签、TF graph dumps)和 flag 绑定的 dump 指令。由 XLA_FLAGS 驱动的 HLO dump 旋钮(--xla_dump_to 等)不是 env vars,而是通过 LIBTPU_INIT_ARGS 通道携带的 flag(见 xla-flag-atlas.md)。
| Variable | Reader / Consumer | Effect |
|---|---|---|
TPU_ML_PLATFORM | libtpu::telemetry::InitializeUptimeMetricViaEnvironmentVariables @ 0x20a65720 | 写入 uptime/runtime telemetry gauge 的 ML-platform 标签(例如框架名称)。 |
TPU_ML_PLATFORM_VERSION | libtpu::telemetry::InitializeUptimeMetricViaEnvironmentVariables @ 0x20a65720 | 同一 telemetry gauge 的平台版本字符串。 |
TF_DUMP_GRAPH_PREFIX | getenv(TF graph dump) | TensorFlow graph dump 的目录前缀。由字面 getenv 读取(多个站点)。 |
TF_DUMP_GRAPH_NAME_FILTER / _GROUPS / _WRAPPED | getenv(TF graph dump) | graph dump 的名称过滤 / 分组 / wrap 控制。由字面 getenv(DebugDataDumper::LoadEnvvars)读取。 |
TF_DUMP_GRAPH_FMT | tsl::ReadStringFromEnvVar(GetDumpGraphFormatLowerCase @ 0x10d8cf60) | graph dump 的输出格式(默认 "TXT")。通过 tsl env-var helper 读取,不是字面 getenv。 |
TF_GRAPH_TO_HLO_COMPILER_DUMP_DIR | getenv | graph→HLO compiler 的 dump 目录。 |
TF_LOG_XLA_ACTIVITY | getenv | 启用 XLA activity logging。 |
MLIR_CRASH_REPRODUCER_DIRECTORY | getenv(MLIR) | MLIR crash reproducer 的目录。 |
MLIR_BRIDGE_LOG_ENABLE_ONLY_TOP_LEVEL_PASSES | getenv(MLIR) | 将 MLIR bridge logging 限制为 top-level passes。 |
XPROF_SKIP_DROP_EXCESS_XPLANE_BYTES | getenv(xprof) | Profiler XPlane byte-budget 控制。 |
TPU_CORE_DUMP_DIRECTORY | flag/option(字符串存在) | TPU core dump 的目录。 |
TPU_LOG_DIR / TPU_MAX_LOG_SIZE_MB | flag/option(字符串存在) | TPU log 目录 / 大小上限。 |
TPU_VMODULE / TPU_VLOG_LEVEL / TPU_STDERR_LOG_LEVEL | flag/option(字符串存在) | 按模块 / 全局 / stderr 的 verbose-logging 级别。 |
6. 继承的(非 TPU)环境
libtpu 静态链接了一大组 Google 和第三方库,每个库都会读取自己的环境。这些变量在已加载的 .so 中存在且有效,但并不是 TPU runtime 重新实现者需要复现的 TPU 配置表面。这里按家族编目,而不是逐项枚举,因为列表长达约 180 个不同字符串;复现它们就是在复现那些库,而不是复现 libtpu。
| Family | Example variables | Origin |
|---|---|---|
| Process bring-up | GOOGLE_LOG_DIR, GOOGLE_STDERRTHRESHOLD, GOOGLE_MLOCK_HINT, GOOGLE_MAX_LOG_MB, GOOGLE_DEBUG_ON_FAILURE | Google base/ init runtime(在 RealInitGoogle 内运行) |
| Topology discovery | HWLOC_*(~50 vars:HWLOC_XMLFILE, HWLOC_COMPONENTS, HWLOC_FSROOT, …) | vendored hwloc |
| PMU / profiling | LIBPFM_*, CPUPROFILE_*, FREQUENCY, JITDUMPDIR | vendored libpfm / CPU profiler |
| gRPC | GRPC_*(大族) | vendored gRPC |
| Cloud storage | GCS_*(~30 vars), GCE_METADATA_HOST, GOOGLE_APPLICATION_CREDENTIALS, NO_GCE_CHECK | TF/GCS filesystem |
| Symbolization | LLVM_SYMBOLIZER_PATH, LLVM_DISABLE_SYMBOLIZATION, LLVM_OVERRIDE_PRODUCER | vendored LLVM |
| Accelerator paths | CUDA_HOME / CUDA_PATH / CUDA_ROOT, ROCM_HOME / ROCM_PATH / ROCM_ROOT | XLA host probes(对 TPU 路径无影响) |
| Test harness | TEST_TMPDIR, TEST_SRCDIR, TEST_UNDECLARED_OUTPUTS_DIR, UNITTEST_ON_BORG, XML_OUTPUT_FILE | Google test runtime(生产环境中 dormant) |
| Standard POSIX | HOME, PATH, PWD, TMPDIR / TMP / TEMP, TZ / TZDIR | libc / TF utilities |
注意 —
XLA_ALLOW_GET_DEFAULT_PLATFORM是真实的字面getenv读取(位于 XLA platform-manager 层),但它 gate 的是 XLA 的默认平台 fallback,而不是任何 TPU 专属内容。它列在这里而不是 §2 中,因为 TPU-only 重新实现永远不会到达查询它的代码。
7. TPU_LIBRARY_PATH 特例
TPU_LIBRARY_PATH 是用户最常与 libtpu 关联的变量,但 libtpu.so 本身并不会对它调用 getenv。wheel 的 Python wrapper 会设置它:
# libtpu/__init__.py (from the wheel)
if not os.environ.get('TPU_LIBRARY_PATH'):
os.environ['TPU_LIBRARY_PATH'] = get_library_path() # path to this libtpu.so
```text
然后该变量由**框架 loader**(host 进程中的 JAX/PJRT plugin-discovery 代码)读取,用于定位要 `dlopen` 的 `.so`。等 libtpu 自己的代码开始运行时,这个路径已经完成了它的工作。libtpu 的重新实现者不实现 `TPU_LIBRARY_PATH`;*plugin loader* 的重新实现者才实现它。报告中两个已确认的 `TPU_LIBRARY_PATH` 字符串引用是这个 Python assignment 和读取,而不是二进制内部的 `getenv`。
> **怪癖 —** wheel 在 `__init__.py` 中以 *set-if-unset* 方式提供 `TPU_LIBRARY_PATH`,因此导入 `libtpu` 这一步会把框架接到打包的 `.so`。如果在导入*之前*在环境中设置 `TPU_LIBRARY_PATH`,就会覆盖加载哪个 `libtpu.so`——打包的 `__init__.py` 会尊重已有值。这是把 JAX 指向自定义 libtpu 构建的 override hook。
---
## 交叉引用
- [overview.md](overview.md) — 配置表面地图:flags、knobs、编译环境,以及 env vars 在其中的位置
- [../lifecycle/tftpu-initialize-bootstrap.md](../lifecycle/tftpu-initialize-bootstrap.md) — `LIBTPU_INIT_ARGS` 摄取机制(空格拆分、`argv[0]` 合成、flag parse)和 `TPU_LOAD_LIBRARY` 锁 gate
- [xla-flag-atlas.md](xla-flag-atlas.md) — `LIBTPU_INIT_ARGS` 和 `XLA_FLAGS` 实际注入的 `--xla_*` / `--tpu_*` flags
- [flag-families.md](flag-families.md) — flag 名称在解析后如何分组并按前缀分派
- [../megascale/bootstrap/overview.md](../megascale/bootstrap/overview.md) — 消费 `MEGASCALE_*` options 并由 `SKIP_MEGASCALE_PJRT_CLIENT` gate 的 multi-slice bootstrap