-
Notifications
You must be signed in to change notification settings - Fork 417
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
Allow optimum to discover and load subpackages #1894
Conversation
d47be23
to
35e5e79
Compare
The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update. |
33cf651
to
70660ad
Compare
As an alternative to directly adding their commands in a register.py file under the root optimum directory, this adds a decorator to declare a subcommand that can be used by subpackages when they are loaded. This will fix the issue of subcommands 'disappearing' when optimum is upgraded without reinstalling the subpackage.
The onnxruntime commands are moved into a subpackage loader directory. This subpackage directory is only loaded (and its commands added) when the onnxruntime is available. This avoids wrongly indicating that the onnxruntime commands are available when the package is actually not installed.
70660ad
to
40e4f8d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, apart that optimum-cli
has a 1-3s delay to start running (already on main) on my laptop, which should be ideally improved in a future PR
@@ -17,7 +17,7 @@ | |||
from pathlib import Path | |||
from typing import TYPE_CHECKING | |||
|
|||
from .. import BaseOptimumCLICommand | |||
from optimum.commands import BaseOptimumCLICommand |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why absolute path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's mostly because the relative path would have been complicated, but also to serve as a model for actual subpackages that can live outside the optimum tree.
SUBPACKAGE_LOADER = "subpackage" | ||
load_namespace_modules("optimum", SUBPACKAGE_LOADER) | ||
|
||
# Load subpackages from internal modules not explicitly defined as namespace packages | ||
loader_name = "." + SUBPACKAGE_LOADER |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is SUBPACKAGE_LOADER
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the name of the module that is imported in each subpackage to "load" them. I used a constant because I use it twice and was expecting maybe some discussion about the naming.
@@ -15,5 +15,4 @@ | |||
from .base import BaseOptimumCLICommand, CommandInfo, RootOptimumCLICommand | |||
from .env import EnvironmentCommand | |||
from .export import ExportCommand, ONNXExportCommand, TFLiteExportCommand | |||
from .onnxruntime import ONNXRuntimeCommand, ONNXRuntimeOptimizeCommand, ONNXRuntimeQuantizeCommand | |||
from .optimum_cli import register_optimum_cli_subcommand |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would need to make sure register_optimum_cli_subcommand
is not used in subpackages
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are no calls in optimum
and I quickly checked the optimum-XX
to verify that none of them was calling it either, but I was not 100 % sure. If that is an issue I can make it public again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Existing subpackages are using the "register" method at the moment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is super cool!
Thanks for this improvement @dacorvo
if sys.version_info >= (3, 8): | ||
from importlib import metadata as importlib_metadata | ||
else: | ||
import importlib_metadata |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That raises the question for later: what is the minimal python version we want to support. I have seen different things accross differents huggingface libraries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Python 3.8 is the oldest supported, EOL is october 2024: https://devguide.python.org/versions/
I guess we could only support 3.8 and newer.
What does this PR do?
This introduces explicitly the concept of
optimum
subpackages that are loaded "dynamically" by theoptimum-cli
(and possibly in the future by other high-level abstraction modules that would require backend-specific implementations).An
optimum
subpackage is primarily a package under theoptimum
namespace, but it can be also a module inside theoptimum
package itself, even if that module does not have its ownpyproject.toml
orsetup.py
(as a real namespace package would).By convention, loading a subpackage means importing a
subpackage
module available at the root of the package.This pull-request first adds a
load_subpackages
helper that will go through the installed namespace packages and try to "load" them.It then adds a decorator to declare custom subcommands, using the same convention as the one already used in the
register
files.This is by using this decorator that each subpackage can add its own subcommands, as it will be called by the
optimum-cli
when evaluating its commands.In order to validate the new helpers, the
onnxruntime
commands are moved inside anonnxruntime/subpackage
directory that is explicitly loaded byload_subpackages
, but only it theonnxruntime
package is available.This improves the UX when using the
optimum-cli
:optimum
installation,onnxruntime
commands will only be available if the package is actually installed.