Skip to content
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

External package integration using plugins #126

Conversation

lorenzomammana
Copy link
Contributor

Repost of #102

At the current stage there's a somehow simple way to include new tasks using the --include_external flag, yet there's no way to include external models except from cloning the lmms-eval repository and doing modifications on it, which might not be the ideal scenario in many cases (for example when developing new models internally).

In my scenario I would like to work on an external package (let's say it's an lmms-eval plugin) without the necessity of cloning this repository (using it as a package)

Right now I've done a fork of the repository which allows loading external tasks and models using an environment variable called LMMS_EVAL_PLUGINS to include external repositories (like LMMS_EVAL_PLUGINS=package1,package2), particularly in the __main__.py I'm able to integrate new tasks in this way

if os.environ.get("LMMS_EVAL_PLUGINS", None):
    for plugin in os.environ["LMMS_EVAL_PLUGINS"].split(","):
        package_tasks_location = importlib.util.find_spec(f"{plugin}.tasks").submodule_search_locations[0]
        eval_logger.info(f"Including path: {args.include_path}")
        include_path(package_tasks_location)

Assuming that there's a package installed which follows the same structure as lmms-eval, this piece of code retrieves all the content of {package_name}.tasks and includes them as tasks.

In a similar way I've modified the __init__.py of models

if os.environ.get("LMMS_EVAL_PLUGINS", None):
    # Allow specifying other packages to import models from
    for plugin in os.environ["LMMS_EVAL_PLUGINS"].split(","):
        m = importlib.import_module(f"{plugin}.models")
        for model_name, model_class in getattr(m, "AVAILABLE_MODELS").items():
            try:
                exec(f"from {plugin}.models.{model_name} import {model_class}")
            except ImportError:
                pass

In a similar way assuming that there's an external package that follows the same structure as lmms-eval, this piece of code will read the AVAILABLE_MODELS dict from the external package and register new models to be used by lmms-eval.

I've tested this with an external package named lvlm_benchmarks where I'm trying a few models that are not included in this repo (I could contribute with them as well but they are just ugly implementations 😄)

immagine

The __init__.py of models contains simply

AVAILABLE_MODELS = {
    "cogvlm": "CogVLM",
    "textmonkey": "TextMonkey",
    "cogvlm2": "CogVLM2",
}

@kcz358
Copy link
Contributor

kcz358 commented Jun 22, 2024

Thank you for your contribution, I will review the code recently

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it is necessary to have this? Since you can simply use lmms-eval --include-path to include other tasks in your command line

Copy link
Contributor

Choose a reason for hiding this comment

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

I think you should create a function here say include_model just like the include_task and use the file path to include more models instead of the plugins.

I think would be more flexible if user can use something like lmms-eval --include-model <file_path> to include models instead of setting an environment variable

Copy link
Contributor

@kcz358 kcz358 left a comment

Choose a reason for hiding this comment

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

Hi, I think this is an interesting PR and could greatly boost development efficiency for users.

From my point of view, current implementation is not consistent with current code style. I think it would be better and easier to use if we could simply pass in a folder path using arguments even if we can only pass in one task path per inference

@lorenzomammana
Copy link
Contributor Author

Mmm ok, I see that my design is currently disaligned with the current implementation, I can update the PR with your suggestions.

I still really don't like the fact that it's required to specify extra arguments to the CLI every time a user wants to include extra tasks or models, maybe both ways could be included? For the CLI I see as advantage not requiring building a package around tasks and model

@kcz358
Copy link
Contributor

kcz358 commented Jun 23, 2024

From my point of view including models and tasks in command args would be a more explicit way and align with current code style better. I believe would be okay to keep both as current plugin implementation won't affect the pipeline.

@Luodian , Do you mind check this PR also? Which code style do you prefer?

Dannoopsy pushed a commit to Dannoopsy/lmms-eval that referenced this pull request Jun 25, 2024
)

* Resolve conflict when merge the kr_ego with internal_main_dev

* fix the bug of file overwrite

* Optimize the inference of videochatgpt dataset

* Resolve conflict

* delete repeated line

* reformat the code

* rename the file name for inference results

* group the same task together for cvrr and videochatgpt

* group the same task together for videochatgpt and cvrr

* reformat the code

* fix the bug of videochatgpt_consistency multiocessing

* Rename the metric from submission to subtask

* fix the bug of consistency where different answers agre generated in pred2

* add accuracy into the evaluation of cvrr

* add accuracy metric to cvrr dataset

* remove duplicate rows when merging from main branch

* Refactor videochatgpt_gen and videochatgpt_temporal for correct score parsing

* enable the webm video loader for llavavid as required in cvrr dataset

* Refactor process_results function to handle full_docs in videochatgpt task

* add tqdm to consistency gpt_eval

* Refactor the cvrr for correct aggregate logic

* change backend to decord for videochatgpt eval

* Fix for mkv video path

* add perceptiontest dataset test split

* doublecheck and optimize the code in egoschema

* rename metric name of perceptiontest

* add perceptiontest_validation dataset

* remove egoschema aggregate function name

* add temcompass mc dataset

* remove redundant files

* add tempcompass yes_no, captioning, caption_matching subsets

* add all the 5 aspects as metrics

* reformat the output dict for successful match

* remove redundant aggregation function in videochatgpt and rename some function names

* remove redundant aggregation function in activitynetqa and video_detail_description

* remove redundant aggregate functions in cvrr

* remove redundant rows in perception test

* use black ./ to reformat code

* debug: load webm file is now successful

* Remove perceptiontest and perceptiontest_val default template YAML files

* put post prompt in yaml for empcompass dataset

* align gpt eval model name for cvrr and debug the tempcompass in case match is unsuccessful

* "debug tempcompass captioning for multi-choice, and optimze matching rule in egoschema"

* "add a period to each option in egoschema becuase mplugowl always end with period"

* "add readme for egoschema"

* "change readme citation for egoschema"

* "delete redundant print, lint the repo"

---------

Co-authored-by: Bo Li <drluodian@gmail.com>
Co-authored-by: kcz358 <kaichenzhang358@outlook.com>
@Luodian
Copy link
Contributor

Luodian commented Jun 27, 2024

From my point of view including models and tasks in command args would be a more explicit way and align with current code style better. I believe would be okay to keep both as current plugin implementation won't affect the pipeline.

@Luodian , Do you mind check this PR also? Which code style do you prefer?

Thanks for this PR! I take into the look and feel good to merge this.

@Luodian Luodian merged commit 383e7fe into EvolvingLMMs-Lab:main Jun 27, 2024
1 check passed
@lorenzomammana
Copy link
Contributor Author

Nice! I was working exactly right now, I've included a parameter also for the CLI, still believe that's not a good option 😄

This is an example of the infinite command 😅

accelerate launch --num_processes=8 -m lmms_eval --model textmonkey --tasks chords  --batch_size 1 \
--log_samples --log_samples_suffix cogvlm_chords --output_path ./logs/ \
--include_path=/teamspace/studios/this_studio/lvlm-plugin/lvlm_benchmark/tasks/chords/ \
--include_model=/teamspace/studios/this_studio/lvlm-plugin/lvlm_benchmark/models/textmonkey.py:TextMonkey`

@lorenzomammana
Copy link
Contributor Author

I've arrived just 5 minutes too late haha, good I didn't like the last implementation too much 😄

Thanks for your work!

@Luodian
Copy link
Contributor

Luodian commented Jun 27, 2024

Take time, you can still send new PR~

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.

None yet

3 participants