5151logger = logging .getLogger (__name__ )
5252
5353CollateFunction = Callable [..., dict [str , torch .Tensor ]]
54+ _DEEPSEEK_V4_TOKENIZER_SIZE = 129280
55+ _DEEPSEEK_V4_ASSISTANT_TOKEN = "<|Assistant|>"
56+ _DEEPSEEK_V4_ASSISTANT_TOKEN_ID = 128804
5457
5558
5659def _as_source (entry : "HFDatasetSourceConfig | Mapping[str, Any]" ) -> HFDatasetSourceConfig :
@@ -257,6 +260,26 @@ def select_direct_hf_sft_collate(
257260 raise ValueError ("Prompt-completion preprocessing supports text-only examples." )
258261
259262
263+ def _model_collate_key (processor : Any ) -> str :
264+ tokenizer = get_processor_tokenizer (processor )
265+ name_or_path = getattr (tokenizer , "name_or_path" , "" )
266+ convert_tokens_to_ids = getattr (tokenizer , "convert_tokens_to_ids" , None )
267+ try :
268+ has_deepseek_v4_fingerprint = len (tokenizer ) == _DEEPSEEK_V4_TOKENIZER_SIZE and (
269+ callable (convert_tokens_to_ids )
270+ and convert_tokens_to_ids (_DEEPSEEK_V4_ASSISTANT_TOKEN ) == _DEEPSEEK_V4_ASSISTANT_TOKEN_ID
271+ )
272+ except TypeError :
273+ has_deepseek_v4_fingerprint = False
274+ if (
275+ isinstance (name_or_path , str )
276+ and "deepseek-v4" in name_or_path .lower ().replace ("_" , "-" )
277+ and has_deepseek_v4_fingerprint
278+ ):
279+ return "deepseek-v4"
280+ return type (processor ).__name__
281+
282+
260283def load_direct_hf_sft_train_examples (config : DirectHFSFTDatasetConfig ) -> list [dict [str , Any ]]:
261284 """Load the training rows, blending them when the config names several sources."""
262285 sources = config .training_sources
@@ -278,17 +301,24 @@ def build_direct_hf_sft_split(
278301 """Build one requested direct-HF SFT split."""
279302 if target_length <= 0 :
280303 return None
281- from megatron .bridge .data .collators .registry import model_collate_required_for_all_examples
304+ from megatron .bridge .data .collators .registry import always_use_model_collate , resolve_model_collate
282305
283306 if examples is None :
284307 examples = load_direct_hf_sft_examples (source , config .preprocessing )
285- if collate_impl is None and model_collate_required_for_all_examples (type (processor ).__name__ ):
308+ collate_key = _model_collate_key (processor )
309+ if collate_impl is None and always_use_model_collate (collate_key ):
286310 if not isinstance (config .preprocessing , ChatSFTPreprocessingConfig ):
287311 raise ValueError (
288312 f"Processor type '{ type (processor ).__name__ } ' requires chat preprocessing through its "
289313 "model-owned collator."
290314 )
291- selected_collate = None
315+ if collate_key == "deepseek-v4" :
316+ selected_collate = partial (
317+ resolve_model_collate (collate_key ),
318+ loss_mode = config .preprocessing .loss_mode ,
319+ )
320+ else :
321+ selected_collate = None
292322 else :
293323 selected_collate = select_direct_hf_sft_collate (examples , config .preprocessing , collate_impl )
294324 return DirectSFTDataset (
0 commit comments