Data Scientist
You own: experimentation, baseline modeling, statistical rigor, and handing off candidates to MLE for production.
What's new for you
| Was | Now in GeneFlow |
|---|---|
| Local notebooks with scattered metric files | mlflow.start_run() → fully captured in GeneFlow |
| Re-running expensive comparisons by hand | models.compare(a, b) returns metricsDiff + costDiff |
| Cost was opaque | cost_usd is a first-class metric |
| Lineage was tribal knowledge | lineage.upstream(run_id, kind="dataset", id="…") |
Day-1 setup
pip install geneflow
export GENEFLOW_TRACKING_URI=https://api.genedata.io
export GENEDATA_PAT=$(genedata auth token)
Workflow 1 — Track a run from a notebook
import geneflow
geneflow.set_tracking_uri("https://api.genedata.io")
with geneflow.start_run(experiment_name="fraud_eda", run_name="baseline-lr"):
# Train as you do
geneflow.log_params({"C": 1.0, "solver": "lbfgs"})
geneflow.log_metric("auc", 0.81)
geneflow.log_metric("log_loss", 0.34)
geneflow.log_metric("cost_usd", 0.04)
Existing MLflow notebooks: change import mlflow to import geneflow as mlflow and you're done. Or just point MLFLOW_TRACKING_URI.
Workflow 2 — Declare data lineage
geneflow.lineage.upstream(
run_id=run.run_id,
kind="dataset",
id="s3://genedata-acme/datasets/fraud/2026-05-12.parquet",
)
geneflow.lineage.upstream(
run_id=run.run_id,
kind="feature_group",
id="user_features_v2",
)
Now anyone can ask: "what models were trained on user_features_v2?" → lineage.get_downstream(kind="feature_group", id="user_features_v2").
Workflow 3 — Run a sweep
GeneFlow doesn't have a built-in sweep orchestrator, but parent/child runs are first-class:
with geneflow.start_run(experiment_name="fraud_sweep", run_name="parent") as parent:
for lr in [0.001, 0.01, 0.1]:
with geneflow.start_run(experiment_name="fraud_sweep",
run_name=f"lr={lr}", parent_run_id=parent.run_id):
geneflow.log_param("lr", lr)
geneflow.log_metric("auc", train(lr))
The compare UI knows about parent/child relationships.
Workflow 4 — Compare candidates side-by-side
UI: /dashboard/geneflow/ml/compare?run_a=run_abc&run_b=run_def
Shows params, all metric series, and cost_usd deltas in one view. Great for screen-sharing with stakeholders.
Workflow 5 — Hand off to MLE
- Promote your best run to a registered model version:
``python from geneflow import models models.register("fraud-detector") models.create_version("fraud-detector", source=f"runs:/{best_run.run_id}/model", run_id=best_run.run_id, description="DS baseline candidate") ``
- Add a tag on the version with the eval summary
- Open a JIRA / Slack to the MLE owner referencing the version number
Workflow 6 — Reproduce a teammate's run
import json
run = geneflow.get_run("run_abc123")
params = run["data"]["params"] # set-once
tags = run["data"]["tags"]
upstream = geneflow.lineage.get_upstream("run_abc123")
# Pull the dataset version from upstream and retrain
Common gotchas
- Forgetting
cost_usd— it's not auto-computed; you have to log it. Bake it into your training harness so it's never missed. - Don't log secrets in params — params are visible to anyone with read access on the experiment. Use tags/links instead.
- Step ordering —
step=is what the time-series chart uses; epochs work fine, but mixingstepsemantics across runs makes comparison weird.
Where to go next
- 01-ml-engineer.md — for production-handoff workflows
- 07-data-engineer.md — for feature group lineage
- python-sdk.md