SmartRec: EASE + CoVis + Orchestrator recommenders + serving context - #9
Open
Varfalamei wants to merge 32 commits into
Open
SmartRec: EASE + CoVis + Orchestrator recommenders + serving context#9Varfalamei wants to merge 32 commits into
Varfalamei wants to merge 32 commits into
Conversation
Add RecommenderEASE (rectools EASEModel) plus EASESettings. Warm-only ranker: cold users return empty with a cold strategy marker and are routed by the orchestrator/cascade layer. Same RecommenderModel interface as ALS/Popular (train/recommend/save_model_triton/calc_metrics), so Triton serving and the API contract are unchanged. Offline k-fold benchmarks showed EASE^R beating the production ALS on click and booking targets with higher coverage.
Add RecommenderCoVis (item-item co-occurrence from user baskets) and CoVisSettings. Scores candidates by co-occurrence with the user's real-time history (already passed via the history argument, so no serving-contract change). Returns empty without session history; cold routing is handled by the orchestrator/cascade layer. Stored artifact keeps only top-K neighbors per item.
Single serving policy that composes EASE (warm), CoVis (session) and Popular (global) plus cold segment popularity, with a context-driven cascade: session -> co-vis, warm -> EASE, cold+context -> segment popularity, else global, backfilling to top_n. Session-history items are excluded across all tiers. context (country/region/type) is optional and forwarded from request filters; absent context keeps backward-compatible session/warm/global behaviour. Puts the routing logic in smartrec (offline == online) instead of the API service.
Triton backend now loads the ease/covis/orchestrator model types and parses an optional context tensor (JSON), passing it only to the orchestrator. config.pbtxt declares an optional context input; the client sends it only when provided, so existing models and requests are unaffected.
…ep item features
Dataset.construct(interactions_df=...) on an external-id frame dropped item
features, so PolicyModel._build_item_category returned {} and the category
share cap was a silent no-op inside the e2e protocol. Mirror
cross_validate's own fold-dataset construction (dataset.filter_interactions
with keep_external_ids=True) instead, which preserves features and keeps
external ids working for both hot and cold test users. _fold_frames is now
used only for the external test frame and the train-user set.
Also documents the cold/hot fold-count asymmetry and adds an n_folds column
to the aggregated table.
_fit built C(|basket|, 2) pairs per user with no bound, so bot/power users with large histories could blow up fit time and memory. Add fit_basket_size (default 100) to CoVisModelConfig/init/config round-trip; keep only each user's most recent fit_basket_size interactions before building baskets. Also strengthens test_recommend_respects_whitelist with a non-emptiness assertion so the subset check cannot pass vacuously.
…est imports PolicyModel's session-weight tier is derived from total train interaction count, a proxy for engagement - online serving uses live session events instead, so tier semantics differ. State this explicitly in the class docstring. Also removes unused PolicyModelConfig/SourceSpec imports from test_policy_model.py.
…N_COVIS_ENABLED) One artifact = a model set behind one name. When the flag is ON the two weak ALS session paths are replaced per the offline research (EXPERIMENTS.md 2026-08-02/03): - hot user + session: RRF blend of pure ALS and co-visitation (weights from the policy grid, +6% map@10 vs pure ALS) instead of the 70/30 item-sim mix - unknown user + session: co-visitation (4x the item-sim it replaces), with fallback to the old path when covis has no answer Flag OFF (default): behavior is byte-for-byte unchanged; old pickled artifacts load fine (covis attr guarded in _ensure_lookup_caches). Tests: 7 new (both flag states, all four serving paths), suite 63 passed.
…s strictly by group)
The mechanism these names describe is session handling (history from the request), and 'realtime' in identifiers now clashes with the covis session layer naming. Renamed has_realtime_history -> has_session_history and _recommend_hot_user_with_realtime -> _recommend_hot_user_with_session. Strategy VALUES (model_realtime_*) are untouched - they are the wire contract consumed by the API and logs.
Live dev incident: serving passes history as a numpy array of byte strings; 'if not history' on a multi-element ndarray raises ValueError (inference on als_covis_youtravel failed with StatusCode.INTERNAL). Explicit None/len check plus utf-8 decode of bytes entries. Regression test simulates the exact Triton input shapes (object ndarray of str and of bytes 'id:weight').
… RecommenderALS The old independent 'if substring' checks let the bare covis branch overwrite the ALS load for compound names: als_covis_youtravel was served as an empty-neighbors RecommenderCoVis (seed parsed, 0 results; instant realtime_warm on empty history). Single elif ladder, most specific first.
…fault) Seed recency is multiplied by the API event weight from tour_id:weight history entries (view 1.0 / booking intent 2.0 / paid 3.0). Best click map of the 90d variant grid, nominal booking lift; see EXPERIMENTS.md 2026-08-04.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New recommenders and serving support for the ClickHouse-migration training work
(paired with youtravel-recsys GitLab MR !6, which bumps the submodule pointer to
this branch).
Recommenders
model in offline k-fold, lambda=250 / 30d window).
by co-occurrence with the user's real-time history).
segment popularity (cold, by country/region/type) -> global popularity. Consumes
an optional
item_metaat train time and an optional requestcontext(country)at inference.
Serving
serving/model.pyloads EASE / CoVis / Orchestrator; adds an optionalcontextinput;
config.pbtxtdeclares it.smartrec-clientforwardscontext(metadata-driven, only sent when the modeldeclares it).
Model configs (EASE/CoVis/Orchestrator prod/dev) live in the parent repo
(
app/src/settings.py).