You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 787845a
Browse filesBrowse the repository at this point in the historyBrowse files
feat: Version-pinning for FeatureService (online + offline) (#6718)
* fix: Pin FeatureView version in FeatureService projections
A FeatureService built from a version-pinned FeatureView (e.g.
FeatureView(version="v2")) silently served the promoted version instead
of the pinned one, defeating the guarantee a FeatureService is meant to
provide. Two bugs caused this:
1. FeatureService.__init__ appended the source view's projection without
translating its `version` string into `projection.version_tag` (the
field name_to_use() checks to render "fv@v2").
2. utils._get_feature_views_to_use hard-coded the version as None for the
FeatureService branch, so retrieval always fell through to the
promoted snapshot.
Stamp version_tag from the source view's version in __init__, and read
projection.version_tag (instead of None) during retrieval. The default
version ("latest") leaves version_tag as None, so every existing
unversioned FeatureService is unaffected. Covers both online and offline
retrieval, which share _get_feature_views_to_use.
Signed-off-by: h-sarwat <[email protected]>
* feat: Support string feature references in FeatureService
FeatureService.features now accepts string refs using the same
'<feature_view>[@<version>][:<feature>]' syntax as
get_historical_features/get_online_features, e.g. "driver_stats@v2" or
"driver_stats@v2:trips_today". This lets a service pin a historical
FeatureView version without importing or reconstructing the underlying
object.
String entries are stashed at construction (no registry is available
then) and resolved once, in FeatureStore.apply/plan, via a new
FeatureService.resolve_pending_refs. A pinned ref always resolves from
the registry snapshot for that version; an unversioned ref prefers the
apply batch, then the promoted version. utils._parse_feature_ref is
refactored onto a new _parse_feature_or_view_ref that makes the
':<feature>' suffix optional (whole-view refs); _parse_feature_ref is
unchanged for existing callers.
Signed-off-by: h-sarwat <[email protected]>
* fix: Resolve version-pinned OnDemandFeatureViews in offline retrieval
Offline stores re-fetch OnDemandFeatureViews from the registry
independently of the version-aware online path, using an unversioned
registry.list_on_demand_feature_views. A version-pinned ODFV (e.g. from
a FeatureService pinning a specific ODFV version) therefore either raised
"Could not find feature view from reference odfv@v1:feat" or silently
served the promoted version during get_historical_features.
Add a shared utils._get_requested_on_demand_feature_views that resolves
each ref version-aware — pinned refs via get_feature_view_by_version
(stamping projection.version_tag so name_to_use() matches downstream),
unversioned refs via the promoted list as before. Route the three
unversioned call sites through it: OnDemandFeatureView.get_requested_odfvs,
offline_utils.get_feature_view_query_context, and dask.py's inline
duplicate. This covers every offline backend, which all funnel through
one of those. Unversioned refs are unchanged.
Signed-off-by: h-sarwat <[email protected]>
* docs: Document FeatureService version pinning
Document pinning a historical feature view version inside a
FeatureService, via both string feature refs
("driver_stats@v2:trips_today") and version-pinned FeatureView objects,
on the alpha feature-view-versioning page. Clarify that
enable_online_feature_view_versioning gates both online and offline
versioned resolution (they share one code path), both in the page and in
the RegistryConfig field docstring. Update Known Limitations: offline
version-qualified retrieval and version-pinned feature services are now
supported.
Signed-off-by: h-sarwat <[email protected]>
* fix: Handle unresolved string-ref services in feature service retrieval
Signed-off-by: h-sarwat <[email protected]>
* test: Add integration tests for string-ref FeatureService retrieval
Signed-off-by: h-sarwat <[email protected]>
* fix: Copy projection in object-based FeatureService pinning
Signed-off-by: h-sarwat <[email protected]>
* fix: Resolve string refs against all ODFVs in same apply
Signed-off-by: h-sarwat <[email protected]>
* fix: Reject/resolve unresolved string refs in apply and to_proto
Signed-off-by: h-sarwat <[email protected]>
* test: Add version-pinned string-ref FeatureService retrieval test
Signed-off-by: h-sarwat <[email protected]>
* fix: Apply inference to stored projection, not source view
infer_features mutated feature_grouping.projection, but __init__ now stores
a decoupled copy in feature_view_projections (the serialized object). This
broke schema-less FeatureViews used as a feature subset in a FeatureService.
Mutate the stored projection instead.
Signed-off-by: h-sarwat <[email protected]>
---------
Signed-off-by: h-sarwat <[email protected]>
Version history tracking is **always active** — no configuration needed. Every `feast apply` that changes a feature view automatically records a version snapshot.
44
44
45
-
To enable **versioned online reads** (e.g., `fv@v2:feature`), add `enable_online_feature_view_versioning: true` to your registry config in `feature_store.yaml`:
45
+
To enable **versioned reads** (e.g., `fv@v2:feature`), add `enable_online_feature_view_versioning: true` to your registry config in `feature_store.yaml`:
46
46
47
47
```yaml
48
48
registry:
49
49
path: data/registry.db
50
50
enable_online_feature_view_versioning: true
51
51
```
52
52
53
-
When this flag is off, version-qualified refs (e.g., `fv@v2:feature`) in online reads will raise errors, but version history, version listing, version pinning, and version lookups all work normally.
53
+
Despite the `online` in its name, this flag gates **both** online (`get_online_features`) and offline (`get_historical_features`) versioned resolution — they share the same code path. When it is off, version-qualified refs (e.g., `fv@v2:feature`) raise errors, but version history, version listing, version pinning, and version lookups all work normally.
54
54
{% endhint %}
55
55
56
56
## Pinning to a Specific Version
@@ -92,6 +92,50 @@ After reverting with a pin, you can go back to normal auto-incrementing behavior
92
92
| `"v0"`, `"v1"`, `"v2"`, ... | Pin to a specific version number |
93
93
| `"version0"`, `"version1"`, ... | Equivalent long form (case-insensitive) |
94
94
95
+
## Pinning a Version in a Feature Service
96
+
97
+
A `FeatureService` freezes the exact feature definitions a model was trained and
98
+
served on, so it can pin a specific historical feature view version. Two ways to
99
+
do this:
100
+
101
+
**1. String feature references (recommended).** A `FeatureService` entry may be a
102
+
string using the same `<feature_view>[@<version>][:<feature>]` syntax as
103
+
`get_historical_features`/`get_online_features`. No need to import or reconstruct
104
+
the historical feature view object — the pin is resolved against the registry at
105
+
`feast apply` time:
106
+
107
+
```python
108
+
from feast import FeatureService
109
+
110
+
pinned_service = FeatureService(
111
+
name="model_v1_service",
112
+
features=[
113
+
"driver_stats@v0:trips_today", # pinned version, single feature
114
+
"driver_stats@v1", # pinned version, whole view
115
+
"driver_stats", # latest (unpinned), whole view
116
+
],
117
+
)
118
+
```
119
+
120
+
**2. A version-pinned feature view object.** Passing a `FeatureView(version="v2")`
121
+
object (or a slice of it) into `features` carries its version into the service:
Either way, the resolved projection renders as `driver_stats@v2` and both online
132
+
(`get_online_features`) and offline (`get_historical_features`) retrieval return
133
+
the pinned snapshot instead of the promoted version. An unversioned entry
134
+
(`"driver_stats"` or a `version="latest"` object) behaves exactly as before.
135
+
Requires `enable_online_feature_view_versioning: true` (see
136
+
[Configuration](#configuration)); a pinned string ref only resolves once that
137
+
version exists in the registry's history.
138
+
95
139
## Staged Publishing (`--no-promote`)
96
140
97
141
By default, `feast apply` atomically saves a version snapshot **and** promotes it to the active definition. For breaking schema changes, you may want to stage the new version without disrupting unversioned consumers.
@@ -223,7 +267,6 @@ ambiguity, the following characters are reserved and must not appear in feature
223
267
## Known Limitations
224
268
225
269
- **Online store coverage** — Version-qualified reads (`@v<N>`) are SQLite-only today. Other online stores are follow-up work.
226
-
- **Offline store versioning** — Versioned historical retrieval is not yet supported.
270
+
- **Offline store versioning** — Version-qualified historical retrieval (`get_historical_features`) is supported, including through a version-pinned feature service (see [Pinning a Version in a Feature Service](#pinning-a-version-in-a-feature-service)). It requires `enable_online_feature_view_versioning: true`.
227
271
- **Version deletion** — There is no mechanism to prune old versions from the registry.
228
272
- **Cross-version joins** — Joining features from different versions of the same feature view in `get_historical_features` is not supported.
229
-
- **Feature services** — Feature services always resolve to the active (promoted) version. `--no-promote` versions are not served until promoted.
0 commit comments