Skip to content

Support typed default values for missing features #6715

Description

@addenergyx

Is your feature request related to a problem? Please describe.

Feast returns null for features that are missing or explicitly null, so every consumer has to decide how to impute them independently. We've personally experienced this where a Go serving client might turn a missing transaction count into -1 while the training pipeline transforms to 0. As consumers grow ensuring consistency will become harder. That is training/serving skew created by the absence of a shared convention, and adding a new client means rediscovering each feature's missing-value semantics.

Noticed OnlineResponse.to_tensor(default_value=...) and RetrievalJob.to_tensor(default_value=...) do conversion-time replacement for tensors only. I haven't used these myself but think a similar approach could be implemented for to_dict() and to_df().

Feast owns the schema, registry, retrieval paths, statuses, and the ODFV execution boundary, so it's the only layer that can apply a default consistently before transformations in both the online and historical paths.

Describe the solution you'd like
Declare a typed default on the field:

Field(name="transaction_count", dtype=Int64, default_value=0)

Stored in FeatureSpecV2 as a feast.types.Value on field number 8 (currently free; Value.proto is already imported). Message presence distinguishes "no default" from a valid zero-like default such as 0, 0.0, false, or "".

Applied:

  • after the historical point-in-time join
  • during online retrieval in Python and Go serving
  • before ODFV transformations execute

Could be applied here too but can already be done in the transformer code:

  • to null ODFV outputs whose field declares a default
  • optionally to missing/null RequestSource fields

Describe alternatives you've considered

  1. Client-side imputation: today's workaround duplicates semantics per client and permits skew.
  2. fillna() inside each ODFV: every transformation repeats it, and it doesn't help direct feature retrieval.
  3. A default_values={...} argument on retrieval calls: supports consumer-specific behaviour but establishes no reusable feature semantic, and training and serving can still diverge. Could be layered on later as an override above the schema default.
  4. Defaults in feature tags: avoids the proto change but is stringly typed and makes every runtime reinterpret metadata.

Additional context
Strictly opt-in. A field without default_value behaves exactly as it does today, and old registries without field 8 load unchanged.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions