@@ -19,6 +19,7 @@ class IntRole(IntEnum):
1919 System = 0
2020 Prompter = 1
2121 Assistant = 2
22+ Context = 3
2223
2324
2425class Encoder (object ):
@@ -72,6 +73,9 @@ def format_sft_entry(entry: DatasetEntrySft) -> tuple[list[str], list[int]]:
7273 turns .append (f"<|im_start|>system\n { entry .system_message } <|im_end|>\n " )
7374 roles .append (IntRole .System .value ) # 0
7475 for m in entry .conversation :
76+ if m .context :
77+ turns .append (f"<|im_start|>context\n { m .context } <|im_end|>\n " )
78+ roles .append (IntRole .Context .value ) # 3
7579 if m .role == Role .prompter :
7680 turns .append (f"<|im_start|>user\n { m .text } <|im_end|>\n " )
7781 roles .append (IntRole .Prompter .value ) # 1
@@ -90,6 +94,21 @@ def format_conversation(messages) -> str:
9094 return format_pairs (messages )
9195
9296
97+ def get_dataset_name (d : Dataset ):
98+ if isinstance (d , Subset ):
99+ inner = d
100+ while isinstance (inner , Subset ):
101+ inner = inner .dataset
102+ name = f"Subset of { type (inner ).__name__ } "
103+ if hasattr (inner , "name" ):
104+ name += f" ({ inner .name } )"
105+ else :
106+ name = type (d ).__name__
107+ if hasattr (d , "name" ):
108+ name += f" ({ d .name } )"
109+ return name
110+
111+
93112class TokenStats :
94113 def __init__ (self , name : str , total_samples : int , fraction : float = 1 ):
95114 self .name = name
@@ -156,17 +175,7 @@ def tokenize_dataset(
156175
157176 for i in range (len (datasets )):
158177 d = datasets [i ]
159- if isinstance (d , Subset ):
160- if hasattr (d .dataset , "name" ):
161- name = d .dataset .name
162- else :
163- name = f"Subset of { type (d .dataset ).__name__ } "
164- else :
165- if hasattr (d , "name" ):
166- name = d .name
167- else :
168- name = type (d ).__name__
169-
178+ name = get_dataset_name (d )
170179 frac = 1
171180 if dataset_target_sizes :
172181 frac = fractions [i ]
@@ -257,20 +266,28 @@ def tokenize_dataset(
257266 if jsonl_file :
258267 jsonl_file .close ()
259268
260- print ( f" \n # Stats for { full_prefix } * \n " )
269+ per_dataset_stats . append ( total_stats )
261270
262- for stats in per_dataset_stats :
263- print (f"## Stats for '{ stats .name } ' ({ stats .total_samples } samples ({ stats .fraction :.1%} ))" )
264- print ("-----------------" )
265- print (
266- f" Accepted: { stats .accepted_samples } /{ stats .processed_samples } ({ stats .accepted_samples / stats .processed_samples :.1%} )"
267- )
268- print (f" Accepted tokens: { stats .accepted_tokens } " )
269- print (f" Skipped: { stats .skipped_samples } ({ stats .skipped_samples / stats .processed_samples :.1%} )" )
270- print (f" Min tokens per sample: { stats .min_tokens } " )
271- print (f" Max tokens per sample: { stats .max_tokens } " )
272- print (f" Avg tokens per sample: { stats .accepted_tokens / stats .accepted_samples } " )
273- print ("-----------------\n " )
271+ stats_path = Path (full_prefix + "_stats.txt" )
272+ with stats_path .open ("w" , encoding = "UTF-8" ) as stats_file :
273+ for f in (None , stats_file ):
274+ print (f"\n # Stats for { full_prefix } *\n " , file = f )
275+
276+ for stats in per_dataset_stats :
277+ print (f"## Stats for '{ stats .name } ' ({ stats .total_samples } samples ({ stats .fraction :.1%} ))" , file = f )
278+ print ("-----------------" , file = f )
279+ print (
280+ f" Accepted: { stats .accepted_samples } /{ stats .processed_samples } ({ stats .accepted_samples / stats .processed_samples :.1%} )" ,
281+ file = f ,
282+ )
283+ print (f" Accepted tokens: { stats .accepted_tokens } " , file = f )
284+ print (
285+ f" Skipped: { stats .skipped_samples } ({ stats .skipped_samples / stats .processed_samples :.1%} )" , file = f
286+ )
287+ print (f" Min tokens per sample: { stats .min_tokens } " , file = f )
288+ print (f" Max tokens per sample: { stats .max_tokens } " , file = f )
289+ print (f" Avg tokens per sample: { stats .accepted_tokens / stats .accepted_samples } " , file = f )
290+ print ("-----------------\n " , file = f )
274291
275292
276293def parse_args ():
@@ -381,20 +398,13 @@ def main():
381398 print ("Training dataset sizes (before sampling):" )
382399 total = len (train )
383400 for d in train .datasets :
384- if isinstance (d , Subset ):
385- name = f"Subset of { type (d .dataset ).__name__ } "
386- if hasattr (d .dataset , "name" ):
387- name += f" ({ d .dataset .name } )"
388- else :
389- name = type (d ).__name__
390- if hasattr (d , "name" ):
391- name += f" ({ d .name } )"
401+ name = get_dataset_name (d )
392402 print (f"{ name } : { len (d )} ({ len (d ) / total :.2%} )" )
393403
394404 output_dir .mkdir (parents = True , exist_ok = True )
395405
396406 fn = output_dir / "special_tokens.json"
397- with fn .open ("w" ) as f :
407+ with fn .open ("w" , encoding = "UTF-8" ) as f :
398408 json .dump (encoder .special_tokens , f )
399409
400410 val = ConcatDataset (evals .values ())
0 commit comments