Configure Images and Compute Resources
When deploying Flyte tasks, workloads require specific runtime environments (operating system packages, Python dependencies, custom files) and tailored hardware resources (CPUs, system memory, shared memory, GPUs, TPUs, or hardware slices). In flyte-sdk, you define container images with Image and specify compute constraints with Resources and Device inside a TaskEnvironment.
Defining Images and Resources on a TaskEnvironment
To execute tasks with custom dependencies and allocated compute hardware, declare a TaskEnvironment configured with an Image and a Resources object.
This example could not be verified against this version of the codebase and may not work as shown. Validator finding: 'flyte.Resources' does not accept keyword(s): cpu, disk, gpu, memory, shm
from pathlib import Path
from flyte import Image, Resources, TaskEnvironment
# Define a container image with system and Python dependencies
custom_image = (
Image.from_debian_base(python_version=(3, 12))
.with_apt_packages("curl", "git")
.with_pip_packages("pandas", "torch")
.with_env_vars({"MODEL_CACHE_DIR": "/tmp/cache"})
)
# Define compute resources: 2 CPUs, 8 GiB RAM, 20 GiB disk, auto shared memory, 1 A100 GPU
task_resources = Resources(
cpu=2,
memory="8Gi",
disk="20Gi",
shm="auto",
gpu="A100:1",
)
# Create the task environment
training_env = TaskEnvironment(
name="training_env",
image=custom_image,
resources=task_resources,
)
@training_env.task
async def train_model(batch_size: int) -> str:
return f"Model trained with batch size {batch_size}"
In this setup:
TaskEnvironmentbundles default runtime settings for all tasks registered to it. The fully qualified name for tasks registered on this environment becomestraining_env.<function_name>.Imageuses an immutable, fluent builder starting with a base image constructor (such asfrom_debian_base()) and chaining layer operations (such aswith_apt_packages()andwith_pip_packages()).Resourcesconfigures hardware requirements requested for the task container.
Building and Selecting Container Images
Image objects cannot be instantiated directly via Image() (direct instantiation raises a TypeError). Instead, initialize an Image using a from_* base constructor, then chain with_* methods to add immutable layers.
1. Base Image Constructors
flyte-sdk provides five base constructors:
from pathlib import Path
from flyte import Image
# 1. Official Debian base with a specific Python version (multi-arch by default)
debian_img = Image.from_debian_base(
python_version=(3, 12),
name="my-custom-image",
registry="ghcr.io/my-org",
)
# 2. Existing pre-built registry image
prebuilt_img = Image.from_base("python:3.12-slim-bookworm")
# 3. Custom Dockerfile (cannot be chained with further with_* layers)
dockerfile_img = Image.from_dockerfile(
file=Path("/path/to/Dockerfile"),
name="dockerfile-app",
registry="ghcr.io/my-org",
)
# 4. uv inline dependency script
uv_script_img = Image.from_uv_script(
script=Path("scripts/run.py"),
name="uv-script-image",
registry="ghcr.io/my-org",
)
# 5. Pre-configured image reference name
ref_img = Image.from_ref_name("default")
2. Customizing Image Layers
Chain modification methods to install packages, copy files, and configure the container environment:
from pathlib import Path
from flyte import Image
image = (
Image.from_debian_base(python_version=(3, 11), name="data-pipeline")
# System dependencies via apt-get
.with_apt_packages("build-essential", "libpq-dev")
# Python dependencies via pip
.with_pip_packages("scikit-learn", "pyarrow>=14.0.0")
# Requirements text file
.with_requirements(Path("requirements.txt"))
# Working directory
.with_workdir("/app")
# Environment variables
.with_env_vars({"APP_ENV": "production", "LOG_LEVEL": "INFO"})
# Arbitrary shell commands (do not prefix with RUN)
.with_commands(["mkdir -p /tmp/models", "chmod 777 /tmp/models"])
# Copy local files and directories into the image
.with_source_folder(src=Path("./config"), dst="/app/config")
.with_source_file(src=Path("./setup.cfg"), dst="/app/setup.cfg")
)
3. Managing Projects with uv or Poetry
Install dependencies directly from project lockfiles:
from pathlib import Path
from flyte import Image
# uv project with pyproject.toml and uv.lock
uv_image = Image.from_debian_base(name="uv-app").with_uv_project(
pyproject_file=Path("pyproject.toml"),
uvlock=Path("uv.lock"),
project_install_mode="dependencies_only", # or "install_project"
)
# Poetry project with pyproject.toml and poetry.lock
poetry_image = Image.from_debian_base(name="poetry-app").with_poetry_project(
pyproject_file=Path("pyproject.toml"),
poetry_lock=Path("poetry.lock"),
project_install_mode="dependencies_only",
)
4. Build-Time Secrets for Private Packages
To pull private packages from authenticated registries or repositories during image building, pass secret mounts to with_pip_packages(), with_apt_packages(), or with_requirements():
This example could not be verified against this version of the codebase and may not work as shown. Validator finding: 'flyte.Secret' does not accept keyword(s): key 'flyte.Secret' does not accept keyword(s): key, mount
from pathlib import Path
from flyte import Image, Secret
private_repo_image = (
Image.from_debian_base(name="private-tools")
.with_pip_packages(
"git+https://$GITHUB_PAT@github.com/my-org/private-repo.git",
secret_mounts=[Secret(key="GITHUB_PAT")],
)
.with_apt_packages(
"custom-pkg",
secret_mounts=[Secret(key="apt-secret", mount=Path("/etc/apt/apt-secret"))],
)
)
Configuring Compute Resources
The Resources class defines compute allocations for CPU, system memory, ephemeral disk, shared memory (shm), and hardware accelerators.
CPU and Memory Specifications
You can pass scalar values or request/limit tuples:
This example could not be verified against this version of the codebase and may not work as shown. Validator finding: 'flyte.Resources' does not accept keyword(s): cpu, disk, memory, shm
from flyte import Resources
# Fixed allocations
fixed_res = Resources(
cpu=2, # 2 CPU cores (can also pass 0.5, "500m", "2")
memory="4Gi", # 4 GiB memory ("512Mi", "1Gi", "1G", "4Gi")
disk="50Gi", # Ephemeral local storage
shm="4Gi", # Shared memory for IPC/data loaders, or "auto"
)
# Request and limit ranges using 2-element tuples: (request, limit)
ranged_res = Resources(
cpu=(1, 4), # Request 1 core, limit up to 4 cores
memory=("2Gi", "16Gi"), # Request 2 GiB, limit up to 16 GiB
disk="100Gi",
shm="auto", # Automatically sets /dev/shm to maximum node capacity
)
Configuring Accelerators and Hardware Partitions
Accelerators (NVIDIA GPUs, AMD GPUs, Google Cloud TPUs, AWS Trainium/Inferentia, Habana Gaudi) can be specified on Resources using shorthand strings or explicit Device instances.
String Shorthand
Pass the accelerator model and count formatted as "<Device>:<Quantity>":
This example could not be verified against this version of the codebase and may not work as shown. Validator finding: 'flyte.Resources' does not accept keyword(s): cpu, gpu, memory
from flyte import Resources
# 1 NVIDIA T4 GPU
t4_res = Resources(cpu=2, memory="8Gi", gpu="T4:1")
# 8 NVIDIA A100 80GB GPUs
a100_res = Resources(cpu=16, memory="64Gi", gpu="A100 80G:8")
# 8 NVIDIA H100 GPUs
h100_res = Resources(cpu=32, memory="128Gi", gpu="H100:8")
# AMD MI300X GPU
amd_res = Resources(cpu=8, memory="32Gi", gpu="MI300X:1")
Explicit Device Helpers and MIG / Slice Partitioning
For hardware partitioning (such as Multi-Instance GPU partitioning on NVIDIA A100/H100/H200, or multi-dimensional slice topologies on TPUs), use helper factory functions that return Device instances:
This example could not be verified against this version of the codebase and may not work as shown. Validator finding: 'flyte.Resources' does not accept keyword(s): cpu, gpu, memory
from flyte import AMD_GPU, GPU, HABANA_GAUDI, Neuron, Resources, TPU, TaskEnvironment
# NVIDIA GPU with Multi-Instance GPU (MIG) partition
mig_gpu_env = TaskEnvironment(
name="gpu_mig_env",
resources=Resources(
cpu=4,
memory="16Gi",
gpu=GPU(device="A100", quantity=1, partition="1g.5gb"),
),
)
# Google Cloud TPU v5p with a 2x2x1 slice topology
tpu_env = TaskEnvironment(
name="tpu_env",
resources=Resources(
cpu=8,
memory="32Gi",
gpu=TPU(device="V5P", partition="2x2x1"),
),
)
# AWS Trainium / Inferentia via Neuron
neuron_env = TaskEnvironment(
name="neuron_env",
resources=Resources(
cpu=8,
memory="32Gi",
gpu=Neuron(device="Trn1"),
),
)
# AMD GPU
rocm_env = TaskEnvironment(
name="rocm_env",
resources=Resources(
cpu=8,
memory="32Gi",
gpu=AMD_GPU(device="MI300X"),
),
)
# Habana Gaudi
gaudi_env = TaskEnvironment(
name="gaudi_env",
resources=Resources(
cpu=8,
memory="32Gi",
gpu=HABANA_GAUDI(device="Gaudi1"),
),
)
Overriding and Cloning Configurations
Runtime Resource Overrides with task.override()
Tasks can override compute resources dynamically at invocation time (for example, when retrying after an out-of-memory error):
This example could not be verified against this version of the codebase and may not work as shown. Validator finding: 'flyte.Resources' does not accept keyword(s): cpu, memory 'flyte.Resources' does not accept keyword(s): cpu, gpu, memory
from flyte import Resources, TaskEnvironment
env = TaskEnvironment(
name="dynamic_res_env",
resources=Resources(cpu=1, memory="250Mi"),
)
@env.task
async def memory_intensive_task(data_size: int) -> int:
return data_size * 2
@env.task
async def workflow_entrypoint() -> int:
# Dynamically scale up CPU and memory for this invocation
scaled_task = memory_intensive_task.override(
resources=Resources(cpu=4, memory="8Gi", gpu="T4:1")
)
return await scaled_task(data_size=1000)
Reusing Base Environments with TaskEnvironment.clone_with()
When creating multiple task environments with slight variations, use clone_with() instead of duplicating configurations:
This example could not be verified against this version of the codebase and may not work as shown. Validator finding: 'flyte.Resources' does not accept keyword(s): cpu, memory 'flyte.Resources' does not accept keyword(s): cpu, gpu, memory
from flyte import Image, Resources, TaskEnvironment
base_env = TaskEnvironment(
name="base_env",
image=Image.from_debian_base(python_version=(3, 12)).with_pip_packages("pandas"),
resources=Resources(cpu=2, memory="4Gi"),
)
# Clone with increased resources and spot instance support
heavy_env = base_env.clone_with(
name="heavy_env",
resources=Resources(cpu=8, memory="32Gi", gpu="A100:1"),
interruptible=True,
)
Troubleshooting and Edge Cases
Direct Image() Instantiation Error
Symptom: Calling Image() raises:
TypeError: Direct instantiation of Image not allowed, please use one of the various from_...() methods instead
Fix: Initialize using Image.from_debian_base(), Image.from_base(), Image.from_dockerfile(), Image.from_uv_script(), or Image.from_ref_name().
Layering on Dockerfile-Based Images
Symptom: Calling .with_pip_packages() or other with_* methods on an image created with Image.from_dockerfile() raises:
ValueError: Flyte current cannot add additional layers to a Dockerfile-based Image. Please amend the dockerfile directly.
Fix: Place all package installations, environment variables, and file copies directly inside the Dockerfile when using from_dockerfile().
Invalid Tuple Lengths for CPU or Memory
Symptom: Passing a 1-element or 3-element tuple for cpu or memory (e.g., cpu=(1, 2, 4)) raises:
ValueError: cpu tuple must have exactly two elements
Fix: Always pass exactly two elements representing (request, limit) when using tuple notation: cpu=(1, 2) or memory=("1Gi", "4Gi").
Unrecognized Partition Strings
Symptom: Specifying an invalid partition in GPU() or TPU() raises a ValueError indicating the partition is not valid for that device.
Fix: Match partition strings to supported hardware specifications (e.g., "1g.5gb", "2g.10gb", "3g.20gb", "4g.20gb", "7g.40gb" for NVIDIA A100; "1x1", "2x2x1", "2x2x2", "2x2x4" for Google Cloud TPU V5P).
Overriding Resources on Reusable Environments
Symptom: Calling task.override(resources=...) fails when the task environment is defined with reusable=ReusePolicy(...).
Fix: When overriding resources, env_vars, or secrets on a reusable environment, pass reusable="off" in the same override call:
This example could not be verified against this version of the codebase and may not work as shown. Validator finding: 'flyte.Resources' does not accept keyword(s): memory
from flyte import Resources
await task.override(
resources=Resources(memory="16Gi"),
reusable="off",
)(arg)