@@ -625,3 +625,55 @@ class Qwen3_5TextModel(_Qwen35MtpMixin, _Qwen35MRopeMixin, _LinearAttentionVReor
625625@ModelBase .register ("Qwen3_5MoeForConditionalGeneration" , "Qwen3_5MoeForCausalLM" )
626626class Qwen3_5MoeTextModel (_Qwen35MtpMixin , _Qwen35MRopeMixin , _LinearAttentionVReorderBase ):
627627 model_arch = gguf .MODEL_ARCH .QWEN35MOE
628+
629+
630+ @ModelBase .register ("DFlashDraftModel" )
631+ class DFlashModel (Qwen3Model ):
632+ model_arch = gguf .MODEL_ARCH .DFLASH
633+
634+ def set_vocab (self ):
635+ if self .target_model_dir is None :
636+ raise ValueError (
637+ "DFlash draft model requires --target-model-dir to be specified. "
638+ "Please provide the path to the target model directory containing the tokenizer."
639+ )
640+ logger .info (f"DFlash: Using tokenizer from target model: { self .target_model_dir } " )
641+ original_dir = self .dir_model
642+ self .dir_model = self .target_model_dir
643+ super ().set_vocab ()
644+ self .dir_model = original_dir
645+
646+ def set_gguf_parameters (self ):
647+ super ().set_gguf_parameters ()
648+
649+ block_size = self .hparams .get ("block_size" , 16 )
650+ self .gguf_writer .add_uint32 (f"{ self .gguf_writer .arch } .block_size" , block_size )
651+ dflash_config = self .hparams .get ("dflash_config" , {})
652+
653+ target_layer_ids = dflash_config .get ("target_layer_ids" , [])
654+ if target_layer_ids :
655+ extract_layer_ids = [i + 1 for i in target_layer_ids ]
656+ self .gguf_writer .add_array (f"{ self .gguf_writer .arch } .target_layers" , extract_layer_ids )
657+
658+ mask_token_id = dflash_config .get ("mask_token_id" , None )
659+ if mask_token_id is not None :
660+ self .gguf_writer .add_mask_token_id (mask_token_id )
661+
662+ use_sliding_window = self .hparams .get ("use_sliding_window" , False )
663+ sliding_window = self .hparams .get ("sliding_window" )
664+ layer_types = self .hparams .get ("layer_types" )
665+ if use_sliding_window and sliding_window and layer_types :
666+ is_swa = [lt == "sliding_attention" for lt in layer_types ]
667+ self .gguf_writer .add_sliding_window (sliding_window )
668+ self .gguf_writer .add_sliding_window_pattern (is_swa )
669+
670+ def modify_tensors (self , data_torch : Tensor , name : str , bid : int | None ) -> Iterable [tuple [str , Tensor ]]:
671+ if name == "fc.weight" :
672+ yield (name , data_torch )
673+ return
674+ if name == "hidden_norm.weight" :
675+ yield (self .format_tensor_name (gguf .MODEL_TENSOR .ENC_OUTPUT_NORM ), data_torch )
676+ return
677+ if not name .startswith ("model." ):
678+ name = "model." + name
679+ yield from super ().modify_tensors (data_torch , name , bid )
0 commit comments