`kaggle kernels push` accepts `enable_tpu`/`machine_shape` for TPU but silently provisions the standard (non-TPU) image
Summary
Pushing a kernel with "enable_tpu": true and a TPU machine_shape value via
kaggle kernels push is accepted without error and the kernel runs to completion, but the
resulting environment is the standard CPU/GPU image, not the TPU image. torch_xla is
absent, even though Kaggle's own Kaggle/docker-python repo (tpu/Dockerfile,
tpu/requirements.in) shows the TPU image ships with torch_xla pre-installed. Running the
same notebook via the interactive editor ("Save & Run All") with TPU v5e-8 selected in
Settings → Accelerator correctly allocates a TPU (the session panel shows "TPU v5e-8 On").
This means the push-based API path and the interactive session path diverge in a way that fails silently, no error, no warning, just the wrong environment.
Steps to reproduce
- Set
kernel-metadata.json:(I also tried{ "enable_gpu": false, "enable_tpu": true, "machine_shape": "TpuV5E8" }"Tpu1VmV38", the value documented inkagglesdk'sApiCreateKernelSessionRequest.machine_shapedocstring, which appears to refer to the older TPU v3-8 generation. Both values are accepted by the push API without error.) kaggle kernels push -p <dir>. The push succeeds; kernel status goesQUEUED→RUNNING.- Inside the notebook, print environment info at the start:
import torch print("torch:", torch.__version__, "| cuda:", torch.cuda.is_available()) import torch_xla.core.xla_model as xm # fails - Result (both
machine_shapevalues, reproduced twice each):torch: 2.10.0+cpu | cuda: False ... ModuleNotFoundError: No module named 'torch_xla' - For comparison: open the *same kernel in the interactive editor, select TPU v5e-8 under Settings → Accelerator, and click "Save & Run All". The session panel now shows a "TPU VM" section and "TPU v5e-8 On" a real TPU is allocated this way.
What I'd like clarified / requested
- Is TPU allocation for
kaggle kernels push(the scripted/CI-style path, as opposed to interactive "Save & Run All") supported at all? If so, what is the correct combination ofenable_gpu/enable_tpu/machine_shape(and any other required field) to actually get the TPU image? - If TPU is only available through interactive sessions, it would be very useful to have
kernel-metadata.json'senable_tpu/machine_shapeeither (a) reject TPU values outright for push-based kernels with a clear error, or (b) document this limitation directly, so the failure mode isn't "accepted silently, wrong environment, no error."
Prior related question (no public answer found)
- #286 "[Question] Is there a option to enable TPU and allow kernel to run on TPU after pushing the kernel?", opened 2020, closed 2023 with no visible answer.
Also worth noting as precedent for the general failure pattern (accepted, not honored):
#1192 (merged 2026-09-11) adds a warning specifically when a retired
machine_shapevalue gets silently substituted server-side, same shape of problem, different subset of values (ours is about currently-valid TPU shapes on the push path specifically, not retired ones).#1151 Closed bug where
NvidiaTeslaP100was accepted but didn't actually work with the default image's torch build. The team's own reply there (kaggle-agent) is directly relevant here too:"Reject / warn on P100 + incompatible image, this is the fair, still-open part of your report. P100 is advertised as a valid
machine_shapewith no caveat while being unusable with the default image. We've filed an internal bug to add that caveat to the CLI docs and SDK."That's the exact same complaint we're raising here, just for TPU instead of P100, the team has already agreed this class of gap ("advertised without a caveat, silently doesn't do what it says") is fair to fix.
This is a companion report to #1196 ("machine_shape has no documented value for the 'GPU T4 ×2'
option shown in the notebook editor"), which covers the same general pattern for a different
accelerator option offered by the editor UI.
Why this matters
This came up while trying to move a personal ML training pipeline (which already runs
successfully via kaggle kernels push on GPU) onto the free TPU quota to parallelize development
across separate accelerator pools. The whole point of scripting kernel pushes (vs. manually
clicking through the editor each time) is reproducible, unattended runs, if TPU can only be
reached by a person clicking "Save & Run All" in the browser, that's a meaningful limitation worth
documenting explicitly, since right now it only surfaces as a confusing ModuleNotFoundError
deep in a training script with no indication that the accelerator request itself was ignored.
Environment
- Kaggle Notebooks (Python),
kaggleCLI /kagglesdk. - Base image observed on the "TPU" push attempts:
torch 2.10.0+cpu(i.e., indistinguishable from the default CPU/GPU image, not the TPU image described inKaggle/docker-python'stpu/directory, which pinsTORCH_VERSION=2.8.0plustorch_xla,jax[tpu], etc. as of themainbranch at the time of writing).
Source: Kaggle/kaggle-cli