Benjamin02 commited on
Commit
d461963
·
verified ·
1 Parent(s): 6003b73

Import from GAIR/DataOrchestra; rename to Orchestrator, update model paths and arXiv link

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ base_model: Qwen/Qwen3-1.7B-Base
4
+ language:
5
+ - en
6
+ library_name: transformers
7
+ pipeline_tag: text-generation
8
+ tags:
9
+ - pretraining-data
10
+ - data-curation
11
+ - data-cleaning
12
+ - dataorchestra
13
+ ---
14
+
15
+ # DataOrchestra — Orchestrator Model
16
+
17
+ ## Model Details
18
+
19
+ | | |
20
+ | --- | --- |
21
+ | Base model | [`Qwen/Qwen3-1.7B-Base`](https://huggingface.co/Qwen/Qwen3-1.7B-Base) |
22
+ | Role | Orchestrator (plan generator) |
23
+ | Input | one pretraining-data chunk (≤ 1024 Qwen3 tokens) |
24
+ | Output | a flat JSON plan (`decision` + NP / SR / PA) |
25
+ | Inference mode | non-thinking, greedy decoding |
26
+
27
+
28
+ ## Usage
29
+
30
+ The wire format is a one-line system prompt plus the raw chunk wrapped in `[DOC]` / `[/DOC]`. The model responds with a single JSON plan.
31
+
32
+ ```python
33
+ import json
34
+ from transformers import AutoModelForCausalLM, AutoTokenizer
35
+
36
+ MODEL = "DataOrchestra/Orchestrator"
37
+ tokenizer = AutoTokenizer.from_pretrained(MODEL)
38
+ model = AutoModelForCausalLM.from_pretrained(MODEL, torch_dtype="auto", device_map="auto")
39
+
40
+ SYSTEM_PROMPT = "You are an excellent orchestrator for pretraining data cleaning."
41
+
42
+
43
+ def plan_for_chunk(chunk: str) -> dict:
44
+ messages = [
45
+ {"role": "system", "content": SYSTEM_PROMPT},
46
+ {"role": "user", "content": f"[DOC]\n{chunk}\n[/DOC]"},
47
+ ]
48
+ text = tokenizer.apply_chat_template(
49
+ messages,
50
+ tokenize=False,
51
+ add_generation_prompt=True,
52
+ enable_thinking=False, # orchestrator runs non-thinking
53
+ )
54
+ inputs = tokenizer(text, return_tensors="pt").to(model.device)
55
+ generated = model.generate(
56
+ **inputs,
57
+ max_new_tokens=1024,
58
+ do_sample=False, # greedy: temperature 0.0 / top_p 1.0
59
+ )
60
+ response = tokenizer.decode(
61
+ generated[0][inputs.input_ids.shape[1]:], skip_special_tokens=True
62
+ )
63
+ return json.loads(response)
64
+
65
+
66
+ chunk = (
67
+ "Home | About | Contact\n\n"
68
+ "The Pythagorean theorem states that a^2 + b^2 = c^2 for a right triangle. "
69
+ "It is one of the most fundamental results in geometry.\n\n"
70
+ "Click here to subscribe to our newsletter!"
71
+ )
72
+ print(json.dumps(plan_for_chunk(chunk), indent=2, ensure_ascii=False))
73
+ ```
74
+
75
+ ### Serving with vLLM
76
+
77
+ For high-throughput curation, serve the model with an OpenAI-compatible endpoint:
78
+
79
+ ```bash
80
+ vllm serve DataOrchestra/Orchestrator --served-model-name DataOrchestra-Orchestrator --trust-remote-code
81
+ ```
82
+
83
+ ```python
84
+ from openai import OpenAI
85
+
86
+ client = OpenAI(base_url="http://127.0.0.1:8000/v1", api_key="EMPTY")
87
+ resp = client.chat.completions.create(
88
+ model="DataOrchestra-Orchestrator",
89
+ messages=[
90
+ {"role": "system", "content": "You are an excellent orchestrator for pretraining data cleaning."},
91
+ {"role": "user", "content": "[DOC]\n<your chunk here>\n[/DOC]"},
92
+ ],
93
+ temperature=0.0,
94
+ max_tokens=1024,
95
+ extra_body={"chat_template_kwargs": {"enable_thinking": False}},
96
+ )
97
+ print(resp.choices[0].message.content)
98
+ ```
99
+
100
+ ## Output Schema
101
+
102
+ The orchestrator returns a flat plan JSON:
103
+
104
+ ```json
105
+ {
106
+ "decision": "clean",
107
+ "noise_pruning": true,
108
+ "surface_rectification": "Remove the navigation header and the newsletter call-to-action; keep the statement of the theorem.",
109
+ "pedagogical_augmentation": "Add an intuitive explanation of why a^2 + b^2 = c^2 holds, with a worked example."
110
+ }
111
+ ```
112
+
113
+ | Field | Type | Meaning |
114
+ | --- | --- | --- |
115
+ | `decision` | `"drop"` \| `"untouch"` \| `"clean"` | top-level gate; only `clean` triggers the stages below |
116
+ | `noise_pruning` | `bool` | run the NP tool model (whole-line `remove_lines` edits) |
117
+ | `surface_rectification` | `str` \| `null` | if a string, run SR with this chunk-specific instruction; `null` skips |
118
+ | `pedagogical_augmentation` | `str` \| `null` | if a string, run PA with this chunk-specific instruction; `null` skips |
119
+
120
+ For `drop` / `untouch` decisions, all three stage fields are inert.
121
+
122
+
123
+ ## Citation
124
+
125
+ If you find this work useful, please cite:
126
+
127
+ ```bibtex
128
+ @article{dataorchestra2026,
129
+ title = {DataOrchestra: Learning to Orchestrate Per-Example Curation of Pretraining Data},
130
+ author = {Huang, Zhen and Wang, Yikun and Xia, Shijie and Liu, Pengfei},
131
+ year = {2026},
132
+ journal = {arXiv preprint arXiv:2607.24717}
133
+ }
134
+ ```
chat_template.jinja ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- if messages[0].role == 'system' %}
2
+ {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }}
3
+ {%- endif %}
4
+ {%- for message in messages %}
5
+ {%- if (message.role == "user") or (message.role == "system" and not loop.first) %}
6
+ {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }}
7
+ {%- elif message.role == "assistant" %}
8
+ {{- '<|im_start|>assistant\n' + message.content + '<|im_end|>' + '\n' }}
9
+ {%- endif %}
10
+ {%- endfor %}
11
+ {%- if add_generation_prompt %}
12
+ {{- '<|im_start|>assistant\n' }}
13
+ {%- endif %}
config.json ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "Qwen3ForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": null,
8
+ "dtype": "bfloat16",
9
+ "eos_token_id": 151645,
10
+ "head_dim": 128,
11
+ "hidden_act": "silu",
12
+ "hidden_size": 2048,
13
+ "initializer_range": 0.02,
14
+ "intermediate_size": 6144,
15
+ "layer_types": [
16
+ "full_attention",
17
+ "full_attention",
18
+ "full_attention",
19
+ "full_attention",
20
+ "full_attention",
21
+ "full_attention",
22
+ "full_attention",
23
+ "full_attention",
24
+ "full_attention",
25
+ "full_attention",
26
+ "full_attention",
27
+ "full_attention",
28
+ "full_attention",
29
+ "full_attention",
30
+ "full_attention",
31
+ "full_attention",
32
+ "full_attention",
33
+ "full_attention",
34
+ "full_attention",
35
+ "full_attention",
36
+ "full_attention",
37
+ "full_attention",
38
+ "full_attention",
39
+ "full_attention",
40
+ "full_attention",
41
+ "full_attention",
42
+ "full_attention",
43
+ "full_attention"
44
+ ],
45
+ "max_position_embeddings": 32768,
46
+ "max_window_layers": 28,
47
+ "model_type": "qwen3",
48
+ "num_attention_heads": 16,
49
+ "num_hidden_layers": 28,
50
+ "num_key_value_heads": 8,
51
+ "pad_token_id": 151643,
52
+ "rms_norm_eps": 1e-06,
53
+ "rope_parameters": {
54
+ "rope_theta": 1000000,
55
+ "rope_type": "default"
56
+ },
57
+ "sliding_window": null,
58
+ "tie_word_embeddings": true,
59
+ "transformers_version": "5.2.0",
60
+ "use_cache": false,
61
+ "use_sliding_window": false,
62
+ "vocab_size": 151936
63
+ }
generation_config.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "do_sample": false,
3
+ "eos_token_id": [
4
+ 151645,
5
+ 151643
6
+ ],
7
+ "max_new_tokens": 2048,
8
+ "pad_token_id": 151643,
9
+ "transformers_version": "5.2.0"
10
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:879e21e07f4d54560488538e27b5d97dae9cb54d4baaa5ad765822e38b48c84d
3
+ size 4063515640
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506
3
+ size 11422650
tokenizer_config.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "backend": "tokenizers",
4
+ "bos_token": null,
5
+ "clean_up_tokenization_spaces": false,
6
+ "eos_token": "<|im_end|>",
7
+ "errors": "replace",
8
+ "is_local": true,
9
+ "model_max_length": 131072,
10
+ "pad_token": "<|endoftext|>",
11
+ "padding_side": "right",
12
+ "split_special_tokens": false,
13
+ "tokenizer_class": "Qwen2Tokenizer",
14
+ "unk_token": null
15
+ }