Skip to content

Dynamically assert model temperature value in argparser #856

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 5 commits into
base: exp-856
Choose a base branch
from

Conversation

dberardi99
Copy link

@dberardi99 dberardi99 commented Mar 12, 2025

A new method get_model_temperature(args: argparse.Namespace) has been added to hardcode the model temperature value based on the model name. The chat session models (namely the ones ending with "-chat" or "-azure") have been treated as the corresponding base models. The temperature values can be found in the following data table #366 (comment)

The temperature value will be automatically aligned to the one of the model chosen only if no temperature has been set (args.temperature == TEMPERATURE). Instead, if a wrong model name is fed (args.model in models.LLM.all_llm_names() == 0), the above method is skipped and the temperature is left unchanged to its default value.

In addition, the default temperature has been changed to 1.0 since it is the one relative to the default model (vertex_ai_gemini-1-5)

Fix #366

@dberardi99
Copy link
Author

Hi @DonggeLiu Could you please review it when you get a chance? Many thanks in advance!

Copy link
Collaborator

@DonggeLiu DonggeLiu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @dberardi99.
I left a comment to clarify a bit more about the task.
Please let me know if that makes sense : )

@@ -46,7 +46,7 @@
# Model hyper-parameters.
MAX_TOKENS: int = 2000
NUM_SAMPLES: int = 1
TEMPERATURE: float = 0.4
TEMPERATURE: float = 1.0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ops let's keep the default temperature the same for now to avoid causing surprising results in other people's recent experiments.
We can grid search for the best default values for our use case later.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect, I got it. I'll reset it to its prior value

@@ -279,6 +279,9 @@ def parse_args() -> argparse.Namespace:

if args.temperature:
assert 2 >= args.temperature >= 0, '--temperature must be within 0 and 2.'

if args.temperature == TEMPERATURE and args.model in models.LLM.all_llm_names():
args.temperature = run_one_experiment.get_model_temperature(args)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reckon the issue we solve has 2 tasks:

  1. Main: Different models have different temperature ranges, we want to assert that if user specified a temperature in args, then it should fall into the corresponding models range.
  2. Minor: Define a default temperature for each model.

let's solve the main task first:
1.1. Define the temperature rate for each model class in https://github.com/google/oss-fuzz-gen/blob/main/llm_toolkit/models.py. Use inheritance to minimize the changes needed.
1.2. Replace this hardcoded assertion with dynamic assertion based on the model name:

if args.temperature:
assert 2 >= args.temperature >= 0, '--temperature must be within 0 and 2.'

Then we can work on the minor task:

  1. Add default temperatures under each class.
  2. Set the temperature as the default value here, if user did not specify it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything's clear! Just one thing, do you prefer to solve only the different temperature ranges in this PR or to implement both temperature ranges and default temperatures here?

@dberardi99 dberardi99 requested a review from DonggeLiu March 14, 2025 21:15
Copy link
Collaborator

@DonggeLiu DonggeLiu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @dberardi99, some nits.

@@ -61,6 +61,8 @@ class LLM:

_max_attempts = 5 # Maximum number of attempts to get prediction response

temperature_range: list[float] = [0.0, 2.0] # Default model temperature range
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep this attribute but make the value a constant like TEMPERATURE defined at the top of the file:

temperature_range: list[float] = TEMPERATURE_RANGE

if (hasattr(subcls, 'temperature_range') and hasattr(subcls, 'name')
and subcls.name != AIBinaryModel.name):
ranges[subcls.name] = subcls.temperature_range
return ranges
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, you are replicating all_llm_names.
Would it be more maintainable and extensible to extract and reuse the repeating logic of these two functions? E.g., a function to return all models so that we can reuse it to acquire other attributes in the future.

    @classmethod
    def _all_llm_models(cls):
        """
        Returns a list of LLM model classes that have a `name` attribute
        and are not `AIBinaryModel`.
        """
        models = []
        for subcls in cls.all_llm_subclasses():
            # May need a different filter logic here.
            if subcls.name != AIBinaryModel.name:
                models.append(subcls)
        return models

    @classmethod
    def all_llm_names(cls) -> list[str]:
        """Returns the current model name and all child model names."""
        return [m.name for m in cls._all_llm_models()]

    @classmethod
    def all_llm_temperature_ranges(cls) -> dict[str, list[float, float]]:
        """Returns the current model name and all child model temperature ranges."""
        return {
            m.name: m.temperature_range
            for m in cls._all_llm_models()
            if hasattr(m, 'temperature_range')
        }

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to adjust/simplify these functions as you see fit, particular the filtering logic.
These above are just examples.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! I've slightly modified it by introducing the all_llm_search method, which allows to output the desired attribute for all LLMs. If you don't like the idea, I can switch back to your implementation.

ranges = models.LLM.all_llm_temperature_ranges()
assert ranges[args.model][1] >= args.temperature >= ranges[args.model][0], (
f'--temperature must be within {ranges[args.model][0]} and '
f'{ranges[args.model][1]}.')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add ... for model args.model specify the model name we parsed.

@DonggeLiu DonggeLiu marked this pull request as draft April 11, 2025 06:02
@dberardi99 dberardi99 requested a review from DonggeLiu April 12, 2025 17:43
@dberardi99
Copy link
Author

dberardi99 commented Apr 12, 2025

@DonggeLiu I'm so sorry for the great delay... If you like this final implementation I can open a new PR creating a new branch for this fix in order to leave the modification history clearer.

Copy link
Collaborator

@DonggeLiu DonggeLiu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @dberardi99.
This is already pretty good, just a final question regarding reliability.

I don't think you have to create a new PR, as the modification history is pretty clear. But please let me know if you prefer otherwise.

Also, as your code is almost ready to merge, I will create a new base (#986) for your PR so that we can experiment with it before merging into main.

names = cls.all_llm_search('name')
tr = cls.all_llm_search('temperature_range')
for i in range(len(names)):
out[names[i]] = tr[i]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tr and names may mismatch.
This code assumes that all_llm_subclasses will always return the subclasses in the same order, but I don't think Python's __subclasses__ can guarantee that.

Copy link
Author

@dberardi99 dberardi99 Apr 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've had the same your doubt regarding the order in which Python returns subclasses. I've done lots of tests and the order was always the same, but I can make additional researches and in case we are unsure about it propose a small fix to increase reliability

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about using dictionaries like we discussed earlier?
#856 (comment)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've slightly adapted the filtering function to return also all the models names, so that now we guarantee the correct assignment between model name and temperature range

@dberardi99
Copy link
Author

Thanks @dberardi99. This is already pretty good, just a final question regarding reliability.

I don't think you have to create a new PR, as the modification history is pretty clear. But please let me know if you prefer otherwise.

Also, as your code is almost ready to merge, I will create a new base (#986) for your PR so that we can experiment with it before merging into main.

Awesome! We can continue working in this PR with no problem in this case

@dberardi99 dberardi99 requested a review from DonggeLiu April 16, 2025 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Assert temperature in argparser
2 participants