From bf730c3c0ed36d4ec444ff1ab75cf4bbcf2f3d0f Mon Sep 17 00:00:00 2001 From: raushan Date: Wed, 17 Dec 2025 13:43:05 +0100 Subject: [PATCH 1/5] fix --- src/transformers/generation/utils.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index f97828a0862b..1717419b0ae8 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -410,14 +410,7 @@ def adjust_generation_fn( logger.info( "Generation config file not found, using a generation config created from the model config." ) - self.generation_config = GenerationConfig.from_pretrained( - pretrained_model_name_or_path, - config_file_name="config.json", - _from_auto=from_auto_class, - _from_pipeline=from_pipeline, - _from_model_config=True, - **repo_loading_kwargs, - ) + # Load custom generate function if `pretrained_model_name_or_path` defines it (and override `generate`) if hasattr(self, "load_custom_generate") and trust_remote_code: try: From 7b469fff41d3d678a4e9a0a864575eecf5f0692a Mon Sep 17 00:00:00 2001 From: raushan Date: Wed, 17 Dec 2025 13:53:10 +0100 Subject: [PATCH 2/5] add comment --- src/transformers/generation/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index 1717419b0ae8..16dd4d6e8cf1 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -407,6 +407,7 @@ def adjust_generation_fn( **repo_loading_kwargs, ) except OSError: + # `self` already has a generation config created from model config so we can simply raise a warning logger.info( "Generation config file not found, using a generation config created from the model config." ) From 83d985ca898632bfcb5fabbe4c39a57dd3e0b88b Mon Sep 17 00:00:00 2001 From: raushan Date: Wed, 17 Dec 2025 14:04:43 +0100 Subject: [PATCH 3/5] add a test --- tests/generation/test_utils.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tests/generation/test_utils.py b/tests/generation/test_utils.py index 36e1fc248a47..45fc88afc191 100644 --- a/tests/generation/test_utils.py +++ b/tests/generation/test_utils.py @@ -67,7 +67,6 @@ AutoModelForImageTextToText, AutoModelForSeq2SeqLM, AutoModelForSpeechSeq2Seq, - AutoModelForVision2Seq, BartForConditionalGeneration, BartTokenizer, DataCollatorWithFlattening, @@ -4401,7 +4400,7 @@ def test_generate_vision2text_conditioning(self): """Test that `decoder_input_ids` can be used to condition the generation in vision-to-text models""" pixel_values = floats_tensor((2, 3, 30, 30)) conditioning_input = torch.tensor([[10], [10]]) # this should be the 2nd output token, after the BOS token - model = AutoModelForVision2Seq.from_pretrained( + model = AutoModelForImageTextToText.from_pretrained( "hf-internal-testing/tiny-random-VisionEncoderDecoderModel-vit-gpt2" ) pixel_values = pixel_values.to(torch_device) @@ -4421,6 +4420,24 @@ def test_generate_vision2text_conditioning(self): self.assertTrue(np.array_equal(output_sequences_decoder_input_ids, output_sequences_input_ids)) self.assertTrue(np.array_equal(output_sequences_decoder_input_ids[:, 1:2], conditioning_input)) + @pytest.mark.generate + def test_load_generation_config_from_text_subconfig(self): + """ + Tests that generation config is be loaded from model's `text_config` when not present + in the model repo. We should infer the text config correctly and re-use special tokens + for generation. See https://github.com/huggingface/transformers/issues/42794 + """ + model = AutoModelForImageTextToText.from_pretrained( + "hf-internal-testing/tiny-random-LlavaForConditionalGeneration-no-generation-config", + device_map=torch_device, + ) + self.assertTrue(model.generation_config.eos_token_id is not None) + self.assertTrue(model.generation_config.bos_token_id is not None) + self.assertTrue(model.generation_config.pad_token_id is not None) + + # test that we can generate without inputs, i.e. from BOS + _ = model.generate() + @require_read_token @slow @require_torch_accelerator From d628f359f61490faa062d58f477db832c30a54d4 Mon Sep 17 00:00:00 2001 From: raushan Date: Thu, 18 Dec 2025 11:49:26 +0100 Subject: [PATCH 4/5] wording --- src/transformers/generation/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index 16dd4d6e8cf1..302eae1318f2 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -407,7 +407,7 @@ def adjust_generation_fn( **repo_loading_kwargs, ) except OSError: - # `self` already has a generation config created from model config so we can simply raise a warning + # `self` already has a generation config created from model config so we can simply log info logger.info( "Generation config file not found, using a generation config created from the model config." ) From 71b057d00495ea4f6de306ed747a204bd4b3c90b Mon Sep 17 00:00:00 2001 From: raushan Date: Thu, 18 Dec 2025 18:25:49 +0100 Subject: [PATCH 5/5] this is it! --- .../generation/configuration_utils.py | 25 +++++++++++-------- src/transformers/generation/utils.py | 12 ++++++++- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/transformers/generation/configuration_utils.py b/src/transformers/generation/configuration_utils.py index 483ff2bce452..8a88f58c0282 100644 --- a/src/transformers/generation/configuration_utils.py +++ b/src/transformers/generation/configuration_utils.py @@ -1118,20 +1118,25 @@ def from_model_config(cls, model_config: PreTrainedConfig | dict) -> "Generation # Removes all `None` from the model config dict -- this lets the generation config defaults to take hold config_dict = {key: value for key, value in config_dict.items() if value is not None} - generation_config = cls.from_dict(config_dict, return_unused_kwargs=False, _from_model_config=True) # Special case: some models have generation attributes set in the decoder. Use them if still unset in the # generation config (which in turn is defined from the outer attributes of model config). - if not isinstance(model_config, dict): - decoder_config = model_config.get_text_config(decoder=True) - if decoder_config is not model_config: - default_generation_config = GenerationConfig() - decoder_config_dict = decoder_config.to_dict() - for attr in generation_config.to_dict(): - is_unset = getattr(generation_config, attr) == getattr(default_generation_config, attr) - if attr in decoder_config_dict and is_unset: - setattr(generation_config, attr, decoder_config_dict[attr]) + if isinstance(model_config, dict): + decoder_possible_text_config_names = ("decoder", "generator", "text_config") + for text_config_name in decoder_possible_text_config_names: + if text_config := model_config.get(text_config_name): + model_config = text_config + break + else: + model_config = model_config.get_text_config(decoder=True) + model_config = model_config.to_dict() + + default_generation_config = GenerationConfig() + for attr in generation_config.to_dict(): + is_unset = getattr(generation_config, attr) == getattr(default_generation_config, attr) + if attr in model_config and is_unset: + setattr(generation_config, attr, model_config[attr]) # If any `output_...` flag is set to `True`, we ensure `return_dict_in_generate` is set to `True`. if generation_config.return_dict_in_generate is False: diff --git a/src/transformers/generation/utils.py b/src/transformers/generation/utils.py index 302eae1318f2..b1c98ae9d8c6 100644 --- a/src/transformers/generation/utils.py +++ b/src/transformers/generation/utils.py @@ -407,10 +407,20 @@ def adjust_generation_fn( **repo_loading_kwargs, ) except OSError: - # `self` already has a generation config created from model config so we can simply log info + # `self` already has a generation config created from model config, but model config will + # not contain any generation-specific params. These are popped at config's `__init__`. + # Thus we have to load from `config.json` and create a generation config from it (for BART) logger.info( "Generation config file not found, using a generation config created from the model config." ) + self.generation_config = GenerationConfig.from_pretrained( + pretrained_model_name_or_path, + config_file_name="config.json", + _from_auto=from_auto_class, + _from_pipeline=from_pipeline, + _from_model_config=True, + **repo_loading_kwargs, + ) # Load custom generate function if `pretrained_model_name_or_path` defines it (and override `generate`) if hasattr(self, "load_custom_generate") and trust_remote_code: