Skip to content

Commit 409723f

Browse files
committed
wip
1 parent b121fad commit 409723f

2 files changed

Lines changed: 118 additions & 2 deletions

File tree

docs/geneva/deployment/helm.mdx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,10 @@ geneva:
135135
136136
When set, the chart renders a `geneva-defaults` ConfigMap mounted at `/etc/geneva/defaults/`
137137
in the query node and job pods. If no default is configured, jobs must specify a cluster and
138-
manifest explicitly. Individual jobs can override these defaults per call with the `cluster=`
139-
/ `manifest=` parameters — see [Advanced Job Configuration](/geneva/jobs/advanced-job-configuration).
138+
manifest explicitly. Individual transforms can override the default manifest by pinning one
139+
with `@udf` / `@chunker` / `@udtf` (see
140+
[Advanced Job Configuration](/geneva/jobs/advanced-job-configuration)); to override the cluster
141+
at runtime, use an [Advanced Execution Context](/geneva/jobs/contexts).
140142

141143
## Providing a Ray cluster
142144

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
title: Advanced Job Configuration
3+
sidebarTitle: Advanced job configuration
4+
description: Pin the dependency manifest a transform's distributed job runs with using @udf, @chunker, and @udtf.
5+
icon: sliders
6+
---
7+
8+
<Badge color="red">Enterprise-only</Badge>
9+
10+
On LanceDB Enterprise, backfill and refresh jobs run on a managed, distributed execution
11+
environment configured at deployment time:
12+
13+
- the **default cluster** — the compute pool jobs run on, and
14+
- the **default manifest** — the Python dependency environment (image and packages) the
15+
distributed workers run with.
16+
17+
These defaults are set in the [LanceDB Helm chart](/geneva/deployment/helm) and cover most
18+
workloads. When a transform needs dependencies that differ from the deployment default, pin a
19+
**manifest** on the transform itself, as described below.
20+
21+
<Note>
22+
To override the **cluster** a job runs on — for example to route an embedding backfill to a
23+
GPU pool — see [Advanced Execution Contexts](/geneva/jobs/contexts).
24+
</Note>
25+
26+
## Pinning a dependency manifest
27+
28+
A manifest pins the Python image and packages the distributed workers run with. Build one with
29+
the manifest builders, then attach it to your transform with the `manifest=` argument on
30+
`@udf`, `@chunker`, or `@udtf`. The manifest is snapshotted into the column (or view) metadata
31+
when the transform is registered, so every backfill or refresh of that transform uses it
32+
automatically — there is no per-call manifest argument to remember.
33+
34+
```python
35+
import pyarrow as pa
36+
from typing import Iterator, NamedTuple
37+
from geneva import udf, chunker, udtf
38+
from geneva.manifest import GenevaManifest
39+
40+
# Build a manifest that pins the dependencies these transforms need
41+
embed_manifest = (
42+
GenevaManifest.create_pip("embedding-deps")
43+
.pip(["sentence-transformers==3.3.1", "torch==2.5.1"])
44+
.build()
45+
)
46+
```
47+
48+
### `@udf(manifest=...)`
49+
50+
Pin dependencies for a 1:1 computed column:
51+
52+
```python
53+
@udf(data_type=pa.list_(pa.float32(), 384), manifest=embed_manifest)
54+
def embed(text: str) -> list[float]:
55+
from sentence_transformers import SentenceTransformer
56+
model = SentenceTransformer("BAAI/bge-small-en-v1.5")
57+
return model.encode(text, normalize_embeddings=True).tolist()
58+
59+
tbl.add_columns({"embedding": embed})
60+
tbl.backfill("embedding") # the backfill job runs with embed_manifest
61+
```
62+
63+
### `@chunker(manifest=...)`
64+
65+
Pin dependencies for a 1:N [chunker](/geneva/udfs/scalar-udtfs) (scalar UDTF):
66+
67+
```python
68+
class Chunk(NamedTuple):
69+
chunk_index: int
70+
chunk_text: str
71+
72+
@chunker(manifest=embed_manifest)
73+
def split_document(text: str) -> Iterator[Chunk]:
74+
for i, part in enumerate(text.split("\n\n")):
75+
yield Chunk(chunk_index=i, chunk_text=part)
76+
77+
view = db.create_udtf_view("chunks", source=tbl.search(None), udtf=split_document)
78+
view.refresh() # the refresh job runs with embed_manifest
79+
```
80+
81+
### `@udtf(manifest=...)`
82+
83+
Pin dependencies for an N:M [batch UDTF](/geneva/udfs/batch-udtfs):
84+
85+
```python
86+
@udtf(
87+
output_schema=pa.schema([
88+
pa.field("label", pa.string()),
89+
pa.field("count", pa.int64()),
90+
]),
91+
manifest=embed_manifest,
92+
)
93+
def group_stats(source) -> Iterator[pa.RecordBatch]:
94+
df = source.to_pandas()
95+
agg = df.groupby("label").size().reset_index(name="count")
96+
yield pa.RecordBatch.from_pandas(agg)
97+
98+
view = db.create_udtf_view("summaries", source=tbl.search(None), udtf=group_stats)
99+
view.refresh() # the refresh job runs with embed_manifest
100+
```
101+
102+
## Manifest resolution
103+
104+
For a given transform, the manifest is resolved in this order (first match wins):
105+
106+
1. The manifest pinned on the transform via `@udf` / `@chunker` / `@udtf` `manifest=`.
107+
2. For a materialized view, the manifest snapshotted on the view when it was created.
108+
3. The deployment-default manifest from the [LanceDB Helm chart](/geneva/deployment/helm).
109+
110+
<Note>
111+
The `manifest=` argument applies to managed enterprise (`db://`) jobs. For direct
112+
object-storage or local-filesystem connections, configure the dependency environment
113+
explicitly with an [Advanced Execution Context](/geneva/jobs/contexts) instead.
114+
</Note>

0 commit comments

Comments
 (0)