enzofrnt HilarionLefuneste Cursor commited on
Commit
8d69eed
·
1 Parent(s): be4db4a

feat(training): support dataset revision for enrichment branch

Browse files

Ajoute --dataset-revision à train et eval pour charger
FlowRank/labeled_emails@enrichment (20 labels).

Co-authored-by: Hilarion Lefuneste <hilarionlefuneste@tutamail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

Files changed (3) hide show
  1. .gitignore +1 -0
  2. src/mailsort/eval.py +9 -1
  3. src/mailsort/train.py +11 -3
.gitignore CHANGED
@@ -5,6 +5,7 @@ __pycache__/
5
 
6
  # training outputs (local only)
7
  outputs/
 
8
  outputs_smoke/
9
 
10
  # HF caches
 
5
 
6
  # training outputs (local only)
7
  outputs/
8
+ outputs-enrichment/
9
  outputs_smoke/
10
 
11
  # HF caches
src/mailsort/eval.py CHANGED
@@ -11,6 +11,7 @@ from transformers import AutoModelForSequenceClassification, AutoTokenizer, pipe
11
  @dataclass(frozen=True)
12
  class Config:
13
  dataset_id: str
 
14
  model_id_or_path: str
15
  subfolder: str | None
16
  split: str
@@ -28,6 +29,11 @@ def _build_text(subject: str, body: str) -> str:
28
  def _parse_args() -> Config:
29
  p = argparse.ArgumentParser(description="Evaluate a model (local or Hub) against a HF dataset split.")
30
  p.add_argument("--dataset-id", default="FlowRank/labeled_emails")
 
 
 
 
 
31
  p.add_argument("--model", default="outputs", help="Local path OR Hugging Face repo id (e.g. FlowRank/mailSort).")
32
  p.add_argument("--subfolder", default=None, help="Optional subfolder (e.g. model).")
33
  p.add_argument("--split", default="test", help="Which split to evaluate (e.g. test).")
@@ -35,6 +41,7 @@ def _parse_args() -> Config:
35
  a = p.parse_args()
36
  return Config(
37
  dataset_id=a.dataset_id,
 
38
  model_id_or_path=a.model,
39
  subfolder=a.subfolder,
40
  split=a.split,
@@ -45,7 +52,8 @@ def _parse_args() -> Config:
45
  def main() -> int:
46
  cfg = _parse_args()
47
 
48
- ds = load_dataset(cfg.dataset_id)
 
49
  if cfg.split not in ds:
50
  raise SystemExit(f"Split '{cfg.split}' not found. Available: {list(ds.keys())}")
51
 
 
11
  @dataclass(frozen=True)
12
  class Config:
13
  dataset_id: str
14
+ dataset_revision: str | None
15
  model_id_or_path: str
16
  subfolder: str | None
17
  split: str
 
29
  def _parse_args() -> Config:
30
  p = argparse.ArgumentParser(description="Evaluate a model (local or Hub) against a HF dataset split.")
31
  p.add_argument("--dataset-id", default="FlowRank/labeled_emails")
32
+ p.add_argument(
33
+ "--dataset-revision",
34
+ default=None,
35
+ help="Git revision of the dataset repo (branch, tag, or commit).",
36
+ )
37
  p.add_argument("--model", default="outputs", help="Local path OR Hugging Face repo id (e.g. FlowRank/mailSort).")
38
  p.add_argument("--subfolder", default=None, help="Optional subfolder (e.g. model).")
39
  p.add_argument("--split", default="test", help="Which split to evaluate (e.g. test).")
 
41
  a = p.parse_args()
42
  return Config(
43
  dataset_id=a.dataset_id,
44
+ dataset_revision=a.dataset_revision,
45
  model_id_or_path=a.model,
46
  subfolder=a.subfolder,
47
  split=a.split,
 
52
  def main() -> int:
53
  cfg = _parse_args()
54
 
55
+ kwargs = {"revision": cfg.dataset_revision} if cfg.dataset_revision else {}
56
+ ds = load_dataset(cfg.dataset_id, **kwargs)
57
  if cfg.split not in ds:
58
  raise SystemExit(f"Split '{cfg.split}' not found. Available: {list(ds.keys())}")
59
 
src/mailsort/train.py CHANGED
@@ -18,6 +18,7 @@ from transformers import (
18
  @dataclass(frozen=True)
19
  class Config:
20
  dataset_id: str
 
21
  model_name: str
22
  hub_model_id: str
23
  output_dir: str
@@ -41,6 +42,11 @@ def _build_text(subject: str, body: str) -> str:
41
  def _parse_args() -> Config:
42
  p = argparse.ArgumentParser(description="Train & push email classifier to Hugging Face Hub.")
43
  p.add_argument("--dataset-id", default="FlowRank/labeled_emails")
 
 
 
 
 
44
  p.add_argument("--model-name", default="distilbert-base-uncased")
45
  p.add_argument("--hub-model-id", default="FlowRank/mailSort")
46
  p.add_argument("--output-dir", default="outputs")
@@ -54,6 +60,7 @@ def _parse_args() -> Config:
54
  a = p.parse_args()
55
  return Config(
56
  dataset_id=a.dataset_id,
 
57
  model_name=a.model_name,
58
  hub_model_id=a.hub_model_id,
59
  output_dir=a.output_dir,
@@ -67,8 +74,9 @@ def _parse_args() -> Config:
67
  )
68
 
69
 
70
- def _load_ds(dataset_id: str, seed: int) -> DatasetDict:
71
- ds = load_dataset(dataset_id)
 
72
  if "train" in ds and "test" in ds:
73
  return ds # already split
74
  # fallback: split if only a single split exists
@@ -99,7 +107,7 @@ def _compute_metrics(eval_pred):
99
  def main() -> int:
100
  cfg = _parse_args()
101
 
102
- ds = _load_ds(cfg.dataset_id, seed=cfg.seed)
103
  train_split = "train" if "train" in ds else list(ds.keys())[0]
104
  test_split = "test" if "test" in ds else ("validation" if "validation" in ds else None)
105
 
 
18
  @dataclass(frozen=True)
19
  class Config:
20
  dataset_id: str
21
+ dataset_revision: str | None
22
  model_name: str
23
  hub_model_id: str
24
  output_dir: str
 
42
  def _parse_args() -> Config:
43
  p = argparse.ArgumentParser(description="Train & push email classifier to Hugging Face Hub.")
44
  p.add_argument("--dataset-id", default="FlowRank/labeled_emails")
45
+ p.add_argument(
46
+ "--dataset-revision",
47
+ default=None,
48
+ help="Git revision of the dataset repo (branch, tag, or commit).",
49
+ )
50
  p.add_argument("--model-name", default="distilbert-base-uncased")
51
  p.add_argument("--hub-model-id", default="FlowRank/mailSort")
52
  p.add_argument("--output-dir", default="outputs")
 
60
  a = p.parse_args()
61
  return Config(
62
  dataset_id=a.dataset_id,
63
+ dataset_revision=a.dataset_revision,
64
  model_name=a.model_name,
65
  hub_model_id=a.hub_model_id,
66
  output_dir=a.output_dir,
 
74
  )
75
 
76
 
77
+ def _load_ds(dataset_id: str, seed: int, revision: str | None = None) -> DatasetDict:
78
+ kwargs = {"revision": revision} if revision else {}
79
+ ds = load_dataset(dataset_id, **kwargs)
80
  if "train" in ds and "test" in ds:
81
  return ds # already split
82
  # fallback: split if only a single split exists
 
107
  def main() -> int:
108
  cfg = _parse_args()
109
 
110
+ ds = _load_ds(cfg.dataset_id, seed=cfg.seed, revision=cfg.dataset_revision)
111
  train_split = "train" if "train" in ds else list(ds.keys())[0]
112
  test_split = "test" if "test" in ds else ("validation" if "validation" in ds else None)
113