Dependencies#
Kinetic reads one dependency file for each job: a requirements.txt or a
pyproject.toml. Kinetic installs the packages in that file, and your
function can import them on the pod. This page explains how Kinetic finds
the file and which lines Kinetic filters. It also explains how to install
packages from a private index, and lists the pitfalls that cause a missing
import on the pod. The container image mode decides where the packages
install: in the image at build time, or in the pod at start. See
Container Images for that choice.
A first run#
Put a requirements.txt next to your script. Kinetic finds the file
without configuration:
# requirements.txt
keras
numpy
pandas
@kinetic.run(accelerator="tpu-v5litepod-4")
def train():
import pandas as pd # installed on the pod
...
A pyproject.toml works too. Kinetic reads the [project.dependencies]
list from that file. If both files are in the same directory, Kinetic
uses requirements.txt.
Tip
Recommended defaults:
List only the packages that your function imports. A short list makes the image build faster.
Do not pin
jax,jaxlib,libtpu, orlibtpu-nightly. Kinetic filters those lines and installs the JAX version that matches the accelerator.If you already have a
pyproject.tomlfor local development, use that file. You do not need a separaterequirements.txt.
How discovery works#
When you call a decorated function, Kinetic starts at the entry directory: the directory of the module file that defines the function. Kinetic then walks up one directory at a time. At each directory, Kinetic does these steps:
If a file with the name
requirements.txtis in the directory, Kinetic uses that file.If not, and a file with the name
pyproject.tomlis in the directory, Kinetic uses that file and reads[project.dependencies]from it.If neither file is in the directory, Kinetic moves up one directory and does the steps again.
Kinetic examines files only. If a directory has the name
requirements.txt or pyproject.toml, Kinetic ignores that directory
and continues the walk.
The walk has bounds, so that Kinetic does not use a file from outside your project:
Kinetic stops after it examines the first directory that holds a
.gitentry. The entry can be a directory or a file, because a git worktree uses a file. Kinetic examines that directory for a dependency file before the walk stops.Kinetic stops at your home directory and at the root of the file system. Kinetic examines these directories too.
If Kinetic finds no dependency file, the pod gets only the packages that
Kinetic installs in every image: JAX, Keras, cloudpickle,
google-cloud-storage, and Kinetic.
Kinetic writes the name of the selected file into the log on each submit:
Using dependency file: .... If the installed packages are not the
packages that you expected, read this log line first. If both files are
in the selected directory, the log also names the file that Kinetic
selected. Kinetic logs a warning when it finds no .git entry and the
selected file is not in your entry directory. The log therefore always
shows when Kinetic uses a file from outside your entry directory.
Warning
A pyproject.toml file with no [project.dependencies] list still stops
the walk. If your dependencies are in a requirements.txt file above
that directory, Kinetic does not find them. Kinetic logs a warning that
the selected file declares no dependencies, and that the pod gets only
the packages that Kinetic installs in every image. Move or copy your
dependency file into your entry directory.
Kinetic reads [project.dependencies] only. If that list is empty or
absent, Kinetic looks for dependencies in [tool.poetry.dependencies],
[project.optional-dependencies], [dependency-groups], and
dynamic = ["dependencies"]. If Kinetic finds any of those, Kinetic logs
a warning that names the tables. If [project.dependencies] is not
empty, Kinetic installs that list and ignores the other tables without a
warning.
Kinetic ships only the package root in context.zip.
Kinetic can therefore select a dependency file above the package root.
Kinetic installs the packages from that file, but the directory of that
file is not on the pod.
What Kinetic does with the file#
Kinetic logs the selected file. Kinetic then filters the content (see
JAX and accelerator runtimes), hashes
the filtered content into the image tag, and writes the filtered content
to a generated requirements.txt for Cloud Build. A change to the
filtered content causes a new image build on the next run. The build
sees the generated file alone. A line that points to a path on your
machine (-r base.txt, -e ., or ./local-wheel) therefore cannot
resolve, and the install fails inside Cloud Build.
The other container image modes change where the install happens. The prebuilt mode installs a generated file on the pod at start, and rejects a local path line at submit time. A custom image ignores the dependency file.
JAX and accelerator runtimes#
The image that Kinetic builds already contains jax, jaxlib, and the
runtime for the accelerator category: libtpu on TPU, or the CUDA
libraries on GPU. To prevent your dependency file from replacing that
installation, Kinetic removes these entries before the install:
jaxjaxliblibtpulibtpu-nightly
Kinetic logs a warning for each removed line. The warning names the package and tells you how to keep the line.
If you must override the JAX version, for example to test a new release,
append # kn:keep to the line:
jax==0.4.25 # kn:keep
jaxlib==0.4.25 # kn:keep
The marker works in requirements.txt. Use the marker with care. A
mismatch between jax, jaxlib, and the accelerator runtime is a common
cause of crashes that are hard to diagnose.
Note
Kinetic filters physical lines for the image build. If a filtered jax
entry continues onto more lines with a backslash, the continuation lines
stay in the file and can break the install. The output of
pip-compile --generate-hashes has such lines. Keep each entry on one
line.
Private packages#
Cloud Build installs your dependencies into the image. Cloud Build
never receives your project source. The build context holds exactly three
things: the generated Dockerfile, the Kinetic runner script, and the
generated requirements.txt. A pip.conf, an environment variable, or a
credential on your machine or in your project tree does not reach the
build. The only way to tell the installer about a private index is a line
in the dependency file itself.
You have two options:
Add --index-url or --extra-index-url as a line in requirements.txt.
The installer reads these directives and uses them for every package in
the file:
--extra-index-url https://my-org-private-index.example.com/simple
my-private-package==1.2.3
some-public-dep==2.0.0
This option does not work in a pyproject.toml, because [project.dependencies] holds
package specifiers only. This option needs an index that requires no
credentials. Examples: a public index, or an index that the Cloud Build
worker and the pod can reach through network rules alone.
If your private packages need credentials at install time, system
libraries, or special build flags, build a container image that contains
those packages. Pass the image as container_image="<your-image-uri>".
You control the build environment: pip.conf, secret mounts, and
gcloud authentication. See
Container Images.
Warning
Do not put a secret into requirements.txt, for example
https://user:token@host/.... Kinetic uploads the generated
requirements file to the builds bucket as part of the Cloud Build source
(or to the jobs bucket in the prebuilt mode). Anyone with read access to
those buckets or to the build can read the token.
Common dependency pitfalls#
A
jaxpin without# kn:keep. Kinetic drops the line, logs a warning, and installs the JAX version of the image. If you want the pin, add# kn:keep. If you do not want the pin, delete the line.TensorFlow next to JAX. The
tensorflowpackage can also try to use the TPU, and JAX then cannot open the TPU. If you need TensorFlow fortf.dataonly, installtensorflow-cpu. That package does not use the TPU.A package that you installed locally but did not list. Kinetic reads
requirements.txtorpyproject.tomlonly. A package that you installed withpip installin your shell, but did not list in one of those files, is not on the pod.Extras in
pyproject.toml. Kinetic reads[project.dependencies]only. Packages in[project.optional-dependencies]or in[dependency-groups]do not install, and Kinetic logs no warning when[project.dependencies]is not empty. Move those packages into[project.dependencies], or use arequirements.txt.A large dependency set that changes often. A change to the dependency file causes a new image build. If your dependencies change many times a day, see Container Images for a mode that installs at pod start.
An editable install (
pip install -e). An editable install does not appear inrequirements.txt, and Kinetic cannot install it on the pod. Keep the source inside the package root, which Kinetic ships for you. As an alternative, publish the package and pin a released version. A line such as-e .cannot install in the image or on the pod. Kinetic accepts a line such as-e git+https://example.com/pkg, because that line names a remote source.A local path reference. Examples:
-r other.txt,-c constraints.txt,./wheels/foo.whl,file://..., andmypkg @ ./vendor. These lines point to paths that do not exist in the image or on the pod. The install fails inside Cloud Build. The prebuilt mode rejects these lines at submit time and names the line.