@@ -433,6 +433,57 @@ def model_card_note(args):
433433 return f"\n **Note:** { note_contents } \n "
434434
435435
436+ def _model_card_bool (args , name : str ) -> bool :
437+ value = getattr (args , name , False )
438+ if isinstance (value , bool ):
439+ return value
440+ if isinstance (value , (int , float )):
441+ return bool (value )
442+ if isinstance (value , str ):
443+ return value .strip ().lower () in {"1" , "true" , "yes" , "on" }
444+ return False
445+
446+
447+ def _model_card_optional_value (args , name : str ):
448+ value = getattr (args , name , None )
449+ if isinstance (value , (str , int , float , bool )) or value is None :
450+ return value
451+ return None
452+
453+
454+ def _model_card_training_modes (args , model : Optional [ModelFoundation ] = None ) -> str :
455+ lines = []
456+ model_specific_info = ""
457+ if model and hasattr (model , "custom_model_card_training_mode_info" ):
458+ model_specific_info = model .custom_model_card_training_mode_info (args ) or ""
459+ if not isinstance (model_specific_info , str ):
460+ model_specific_info = ""
461+ model_specific_info = model_specific_info .strip ()
462+
463+ if _model_card_bool (args , "nextlat_enabled" ):
464+ lines .append ("- NextLat: Enabled" )
465+ lines .append (f" - Block index: `{ _model_card_optional_value (args , 'nextlat_block_index' )} `" )
466+ lines .append (f" - Weight: `{ _model_card_optional_value (args , 'nextlat_weight' )} `" )
467+ lines .append (f" - State loss: `{ _model_card_optional_value (args , 'nextlat_state_loss' )} `" )
468+ lines .append (f" - KL weight: `{ _model_card_optional_value (args , 'nextlat_kl_weight' )} `" )
469+
470+ if _model_card_bool (args , "xm_enabled" ):
471+ lines .append ("- XM: Enabled" )
472+ lines .append (f" - Candidate count: `{ _model_card_optional_value (args , 'xm_candidate_count' )} `" )
473+ lines .append (f" - Selection scope: `{ _model_card_optional_value (args , 'xm_selection_scope' )} `" )
474+ lines .append (f" - Training target: `{ _model_card_optional_value (args , 'xm_training_target' )} `" )
475+ lines .append (f" - Block size: `{ _model_card_optional_value (args , 'xm_block_size' )} `" )
476+
477+ if not lines and not model_specific_info :
478+ return ""
479+ blocks = []
480+ if model_specific_info :
481+ blocks .append (model_specific_info )
482+ if lines :
483+ blocks .append ("\n " .join (lines ))
484+ return "## Training modes\n \n " + "\n " .join (blocks ) + "\n \n "
485+
486+
436487def save_metadata_sample (
437488 image_path : str ,
438489 image : Union [Image .Image , np .ndarray , list , str , torch .Tensor ],
@@ -772,6 +823,36 @@ def _add_widget_entries(media, asset_prefix: str):
772823 gallery_intro = "You can find some example audio samples in the following gallery:"
773824 else :
774825 gallery_intro = "You can find some example images in the following gallery:"
826+ gallery_section = f"{ gallery_intro } \n \n <Gallery />\n " if has_media else ""
827+ validation_disabled = _model_card_bool (args , "validation_disable" )
828+ validation_intro = (
829+ "Validation was disabled during training."
830+ if validation_disabled
831+ else (
832+ "The main validation prompt used during training was:"
833+ if prompt
834+ else (
835+ "Validation used ground-truth images as an input for partial denoising (img2img)."
836+ if args .validation_using_datasets
837+ else "No validation prompt was used during training."
838+ )
839+ )
840+ )
841+ validation_prompt_block = f"```\n { prompt } \n ```\n " if prompt and not validation_disabled else ""
842+ validation_settings = ""
843+ if not validation_disabled :
844+ validation_settings = f"""## Validation settings
845+ - CFG: `{ StateTracker .get_args ().validation_guidance } `
846+ - CFG Rescale: `{ StateTracker .get_args ().validation_guidance_rescale } `
847+ - Steps: `{ StateTracker .get_args ().validation_num_inference_steps } `
848+ - Sampler: `{ _validation_scheduler_label (model , StateTracker .get_args ())} `
849+ - Seed: `{ StateTracker .get_args ().validation_seed } `
850+ - Resolution{ 's' if ',' in str (StateTracker .get_args ().validation_resolution ) else '' } : `{ str (StateTracker .get_args ().validation_resolution )} `
851+ { f"- Skip-layer guidance: { _skip_layers (args )} " if args .model_family in ['sd3' , 'flux' ] else '' }
852+
853+ Note: The validation settings are not necessarily the same as the [training settings](#training-settings).
854+
855+ """
775856 sage_usage = getattr (args .sageattention_usage , "value" , args .sageattention_usage )
776857 license_metadata = _license_metadata (model )
777858 yaml_content = f"""---
@@ -800,26 +881,11 @@ def _add_widget_entries(media, asset_prefix: str):
800881
801882This is a { model_type (args )} derived from [{ base_model } ](https://huggingface.co/{ base_model } ).
802883
803- { 'The main validation prompt used during training was:' if prompt else 'Validation used ground-truth images as an input for partial denoising (img2img).' if args .validation_using_datasets else 'No validation prompt was used during training.' }
804- { '```' if prompt else '' }
805- { prompt }
806- { '```' if prompt else '' }
884+ { validation_intro }
885+ { validation_prompt_block }
807886
808887{ model_card_note (args )}
809- ## Validation settings
810- - CFG: `{ StateTracker .get_args ().validation_guidance } `
811- - CFG Rescale: `{ StateTracker .get_args ().validation_guidance_rescale } `
812- - Steps: `{ StateTracker .get_args ().validation_num_inference_steps } `
813- - Sampler: `{ _validation_scheduler_label (model , StateTracker .get_args ())} `
814- - Seed: `{ StateTracker .get_args ().validation_seed } `
815- - Resolution{ 's' if ',' in str (StateTracker .get_args ().validation_resolution ) else '' } : `{ str (StateTracker .get_args ().validation_resolution )} `
816- { f"- Skip-layer guidance: { _skip_layers (args )} " if args .model_family in ['sd3' , 'flux' ] else '' }
817-
818- Note: The validation settings are not necessarily the same as the [training settings](#training-settings).
819-
820- { gallery_intro } \n
821-
822- <Gallery />
888+ { validation_settings } { gallery_section }
823889
824890The text encoder { '**was**' if train_text_encoder else '**was not**' } trained.
825891{ 'You may reuse the base model text encoder for inference.' if not train_text_encoder else 'If the text encoder from this repository is not used at inference time, unexpected or bad results could occur.' }
@@ -849,6 +915,7 @@ def _add_widget_entries(media, asset_prefix: str):
849915{ ('- SLA: Enabled (you MUST use SLA for inference; sla_attention.pt contains attention weights)' ) if StateTracker .get_args ().attention_mechanism == 'sla' else '' }
850916{ lora_info (args = StateTracker .get_args ())}
851917
918+ { _model_card_training_modes (args , model = model )}
852919## Datasets
853920
854921{ datasets_str }
0 commit comments