|
| 1 | +# PathwaysJobSet Builder |
| 2 | + |
| 3 | +`PathwaysJobSet` is a client-side Python library designed to generate and |
| 4 | +deploy Kubernetes `JobSet` resources (`kind: JobSet`) for running Pathways |
| 5 | +workloads on GKE. |
| 6 | + |
| 7 | +It serves as a direct replacement for the custom `PathwaysJob` CRD (`kind: |
| 8 | +PathwaysJob`), allowing you to deploy Pathways workloads using standard, |
| 9 | +community-supported `JobSet` resources without needing a custom controller |
| 10 | +installed on your GKE cluster. |
| 11 | + |
| 12 | +--- |
| 13 | + |
| 14 | +## Key Features |
| 15 | + |
| 16 | +- **Client-Side Generation:** Generates standard `JobSet` YAMLs that can be |
| 17 | + inspected, version-controlled, or applied manually. |
| 18 | +- **Standard Headless Execution:** Runs the Pathways Resource Manager (RM) |
| 19 | + and Proxy as standalone containers in the head job. |
| 20 | +- **GCSFuse Integration:** Easily mount GCS buckets to head and/or worker |
| 21 | + pods. |
| 22 | +- **Colocated Python Support:** Inject a colocated Python sidecar container |
| 23 | + into worker pods for multi-agent or hybrid workloads. |
| 24 | +- **Elasticity Support:** Configure elastic slices for dynamic scaling. |
| 25 | + |
| 26 | +--- |
| 27 | + |
| 28 | +## Basic Usage |
| 29 | + |
| 30 | +```python |
| 31 | +from pathwaysutils.experimental.gke import jobset |
| 32 | + |
| 33 | +# 1. Initialize the builder |
| 34 | +pw_jobset = jobset.PathwaysJobSet( |
| 35 | + name="my-pathways-workload", |
| 36 | + namespace="default", |
| 37 | + pathways_dir="gs://my-bucket/pathways-scratch", |
| 38 | + tpu_type="v5e", |
| 39 | + topology="4x8", |
| 40 | + num_slices=1, |
| 41 | +) |
| 42 | + |
| 43 | +# 2. Export to a standard JobSet YAML file |
| 44 | +pw_jobset.export_yaml("jobset.yaml") |
| 45 | + |
| 46 | +# 3. Deploy directly to a GKE cluster (requires kubernetes configured) |
| 47 | +pw_jobset.apply( |
| 48 | + project_id="my-gcp-project", |
| 49 | + region="us-central1", |
| 50 | + cluster_id="my-gke-cluster", |
| 51 | +) |
| 52 | +``` |
| 53 | + |
| 54 | +--- |
| 55 | + |
| 56 | +## Examples |
| 57 | + |
| 58 | +### 1. Single-Slice v5e-32 (Non-elastic) |
| 59 | +A standard single-slice workload on TPU v5e-32 (32 chips, `4x8` topology, 8 |
| 60 | +VMs). |
| 61 | + |
| 62 | +```python |
| 63 | +from pathwaysutils.experimental.gke import jobset |
| 64 | + |
| 65 | +js = jobset.PathwaysJobSet( |
| 66 | + name="v5e-32-headless", |
| 67 | + namespace="default", |
| 68 | + pathways_dir="gs://my-bucket/scratch", |
| 69 | + tpu_type="v5e", |
| 70 | + topology="4x8", |
| 71 | + num_slices=1, |
| 72 | +) |
| 73 | +js.export_yaml("v5e_32_headless.yaml") |
| 74 | +``` |
| 75 | + |
| 76 | +### 2. Multislice v5p-4x4x4 (2 Slices) |
| 77 | +A multislice workload using 2 slices of TPU v5p-4x4x4 (64 chips per slice). |
| 78 | + |
| 79 | +```python |
| 80 | +from pathwaysutils.experimental.gke import jobset |
| 81 | + |
| 82 | +js = jobset.PathwaysJobSet( |
| 83 | + name="v5p-multislice", |
| 84 | + namespace="default", |
| 85 | + pathways_dir="gs://my-bucket/scratch", |
| 86 | + tpu_type="v5p", |
| 87 | + topology="4x4x4", |
| 88 | + num_slices=2, # 2 slices |
| 89 | +) |
| 90 | +js.export_yaml("v5p_multislice.yaml") |
| 91 | +``` |
| 92 | + |
| 93 | +### 3. Multislice v6e with Elasticity |
| 94 | +A multislice workload on TPU v6e-16 (topology `4x4`, 16 chips, 4 VMs per |
| 95 | +slice) with 2 active slices initially, and elasticity configured for up to 4 |
| 96 | +slices. |
| 97 | + |
| 98 | +```python |
| 99 | +from pathwaysutils.experimental.gke import jobset |
| 100 | + |
| 101 | +js = jobset.PathwaysJobSet( |
| 102 | + name="v6e-elastic", |
| 103 | + namespace="default", |
| 104 | + pathways_dir="gs://my-bucket/scratch", |
| 105 | + tpu_type="v6e", |
| 106 | + topology="4x4", |
| 107 | + num_slices=2, # Initial/Active slices |
| 108 | + elastic_slices=4, # Enable elasticity (informs proxy of max slices) |
| 109 | +) |
| 110 | +js.export_yaml("v6e_elastic.yaml") |
| 111 | +``` |
| 112 | + |
| 113 | +### 4. Advanced Features: GCSFuse and Colocated Python |
| 114 | +This example demonstrates chaining advanced features: |
| 115 | + |
| 116 | +- Mounting a GCS bucket to all containers (head and workers) using GCSFuse. |
| 117 | +- Adding a colocated Python sidecar to the worker pods. |
| 118 | + |
| 119 | +```python |
| 120 | +from pathwaysutils.experimental.gke import jobset |
| 121 | + |
| 122 | +js = ( |
| 123 | + jobset.PathwaysJobSet( |
| 124 | + name="advanced-workload", |
| 125 | + namespace="default", |
| 126 | + pathways_dir="gs://my-bucket/scratch", |
| 127 | + tpu_type="v5e", |
| 128 | + topology="4x8", |
| 129 | + num_slices=1, |
| 130 | + ) |
| 131 | + .add_colocated_python() # Injects colocated python sidecar to workers |
| 132 | + .add_gcsfuse( |
| 133 | + containers="all", |
| 134 | + mount_path="/data", |
| 135 | + bucket="my-data-bucket", |
| 136 | + read_only=True, |
| 137 | + ) |
| 138 | +) |
| 139 | +js.export_yaml("advanced_workload.yaml") |
| 140 | +``` |
| 141 | + |
| 142 | +--- |
| 143 | + |
| 144 | +## API Reference: `PathwaysJobSet` |
| 145 | + |
| 146 | +### Constructor `__init__` |
| 147 | + |
| 148 | +```python |
| 149 | +def __init__( |
| 150 | + self, |
| 151 | + name: str, |
| 152 | + namespace: str, |
| 153 | + pathways_dir: str, |
| 154 | + tpu_type: str, |
| 155 | + topology: str, |
| 156 | + num_slices: int, |
| 157 | + max_restarts: int = 0, |
| 158 | + max_slice_restarts: int = 0, |
| 159 | + termination_grace_period_seconds: int | None = None, |
| 160 | + pathways_version: str = "latest", |
| 161 | + jobset_api_version: str = "v1alpha2", |
| 162 | + elastic_slices: int = 0, |
| 163 | + labels: Mapping[str, str] | None = None, |
| 164 | + annotations: Mapping[str, str] | None = None, |
| 165 | + shared_pathways_service: bool = False, |
| 166 | +) |
| 167 | +``` |
| 168 | + |
| 169 | +- `tpu_type`: Supported values include `"v5e"`, `"v5p"`, `"v6e"`, `"v4"`. |
| 170 | +- `elastic_slices`: If `> 0`, enables elasticity by passing |
| 171 | + `--num_elastic_slices` to the Pathways Proxy. |
| 172 | +- `shared_pathways_service`: If `True`, configures the head job to run only |
| 173 | + the Resource Manager (`pathways-rm`). |
| 174 | + |
| 175 | +### Methods |
| 176 | + |
| 177 | +- **`add_colocated_python()`**: Injects a colocated Python container and |
| 178 | + shared memory volume (`/tmp/shared-memory`) into worker pods. |
| 179 | +- **`add_gcsfuse(containers, mount_path, bucket, read_only=False)`**: Mounts |
| 180 | + a GCS bucket using GCSFuse CSI driver. `containers` can be `"head"`, |
| 181 | + `"worker"`, or `"all"`. |
| 182 | +- **`to_dict()`**: Returns the compiled K8s JobSet resource as a Python |
| 183 | + dictionary. |
| 184 | +- **`export_yaml(filepath)`**: Serializes and writes the JobSet to a YAML |
| 185 | + file. |
| 186 | +- **`apply(project_id, region, cluster_id)`**: Deploys the JobSet to the |
| 187 | + specified GKE cluster. Supports delete-and-recreate lifecycle if the JobSet |
| 188 | + already exists. |
0 commit comments