model-compose 0.3.2__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {model_compose-0.3.2/src/model_compose.egg-info → model_compose-0.3.3}/PKG-INFO +41 -2
- {model_compose-0.3.2 → model_compose-0.3.3}/README.md +40 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/pyproject.toml +1 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/cli/compose.py +10 -10
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/context.py +1 -1
- model_compose-0.3.3/src/mindor/core/component/services/model/base.py +102 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/model/model.py +1 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/model/tasks/summarization.py +18 -6
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/model/tasks/text_classification.py +18 -6
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/model/tasks/text_embedding.py +18 -7
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/model/tasks/text_generation.py +18 -6
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/model/tasks/translation.py +19 -7
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/base.py +1 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/services/http_server.py +20 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/webui/gradio.py +52 -10
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/listener/services/http_callback.py +1 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/utils/http_client.py +34 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/utils/image.py +1 -1
- model_compose-0.3.2/src/mindor/core/utils/renderer.py → model_compose-0.3.3/src/mindor/core/utils/renderers.py +6 -26
- model_compose-0.3.3/src/mindor/core/utils/resolvers.py +29 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/context.py +1 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/model/impl/summarization.py +2 -2
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/model/impl/translation.py +2 -2
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/model/impl/common.py +23 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/model/impl/summarization.py +1 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/model/impl/text_embedding.py +1 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/model/impl/text_generation.py +1 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/model/impl/translation.py +1 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/job/impl/random_router.py +1 -1
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/workflow.py +6 -4
- {model_compose-0.3.2 → model_compose-0.3.3/src/model_compose.egg-info}/PKG-INFO +41 -2
- {model_compose-0.3.2 → model_compose-0.3.3}/src/model_compose.egg-info/SOURCES.txt +3 -2
- model_compose-0.3.2/src/mindor/core/component/services/model/base.py +0 -28
- {model_compose-0.3.2 → model_compose-0.3.3}/LICENSE +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/setup.cfg +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/cli/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/base.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/component.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/http_client.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/http_server.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/mcp_client.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/mcp_server.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/model/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/model/tasks/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/shell.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/workflow.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/compose/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/compose/compose.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/compose/manager.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/controller.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/runner/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/runner/client.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/runner/http_client.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/runner/mcp_client.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/runner/runner.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/runtime/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/runtime/docker/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/runtime/docker/context/Dockerfile +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/runtime/docker/docker.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/runtime/specs.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/services/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/services/mcp_server.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/webui/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/controller/webui/webui.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/gateway/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/gateway/base.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/gateway/gateway.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/gateway/services/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/gateway/services/http_tunnel.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/gateway/services/ssh_tunnel.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/listener/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/listener/base.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/listener/listener.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/listener/services/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/logger/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/logger/base.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/logger/logger.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/logger/logging.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/logger/services/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/logger/services/console.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/logger/services/file.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/runtime/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/runtime/docker/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/runtime/docker/docker.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/runtime/env.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/services/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/services/async_service.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/utils/__init__.py +0 -0
- /model_compose-0.3.2/src/mindor/core/utils/expiring.py → /model_compose-0.3.3/src/mindor/core/utils/caching.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/utils/http_request.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/utils/http_status.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/utils/mcp_client.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/utils/ssh_client.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/utils/streaming.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/utils/time.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/utils/workqueue.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/job/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/job/base.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/job/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/job/impl/action.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/job/impl/delay.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/job/impl/if_.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/job/impl/random_router.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/job/impl/switch.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/job/job.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/schema.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/workflow/workflow.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/loader.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/action.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/common.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/http_client.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/http_server.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/mcp_client.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/mcp_server.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/model/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/model/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/model/impl/common.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/model/impl/text_classification.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/model/impl/text_embedding.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/model/impl/text_generation.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/model/model.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/shell.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/action/impl/workflow.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/component.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/common.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/http_client.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/http_server.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/mcp_client.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/mcp_server.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/model/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/model/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/model/impl/text_classification.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/model/impl/types.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/model/model.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/shell.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/types.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/component/impl/workflow.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/compose.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/controller.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/impl/common.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/impl/http_server.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/impl/mcp_server.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/impl/types.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/webui/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/webui/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/webui/impl/common.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/webui/impl/dynamic.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/webui/impl/gradio.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/webui/impl/static.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/controller/webui/webui.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/gateway/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/gateway/gateway.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/gateway/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/gateway/impl/common.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/gateway/impl/http_tunnel.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/gateway/impl/ssh_tunnel.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/gateway/impl/types.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/job/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/job/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/job/impl/action.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/job/impl/common.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/job/impl/delay.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/job/impl/if_.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/job/impl/switch.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/job/impl/types.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/job/job.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/listener/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/listener/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/listener/impl/common.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/listener/impl/http_callback.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/listener/impl/types.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/listener/listener.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/logger/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/logger/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/logger/impl/common.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/logger/impl/console.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/logger/impl/file.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/logger/impl/types.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/logger/logger.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/runtime/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/runtime/impl/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/runtime/impl/common.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/runtime/impl/docker.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/runtime/impl/native.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/runtime/impl/types.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/schema/runtime/runtime.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/utils/__init__.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/utils/annotation.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/dsl/utils/enum.py +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/model_compose.egg-info/dependency_links.txt +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/model_compose.egg-info/entry_points.txt +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/model_compose.egg-info/requires.txt +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/src/model_compose.egg-info/top_level.txt +0 -0
- {model_compose-0.3.2 → model_compose-0.3.3}/tests/test_cli.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: model-compose
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: model-compose: Declarative AI Model and Workflow Orchestrator
|
|
5
5
|
Author-email: Hanyeol Cho <hanyeol.cho@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -248,7 +248,46 @@ Once enabled, the Web UI will be available at:
|
|
|
248
248
|
```
|
|
249
249
|
http://localhost:8081
|
|
250
250
|
```
|
|
251
|
-
|
|
251
|
+
|
|
252
|
+
## 🎨 Custom Web UI
|
|
253
|
+
You can fully customize the Web UI experience by specifying a different driver or serving your own frontend.
|
|
254
|
+
|
|
255
|
+
By default, `model-compose` uses [Gradio](https://www.gradio.app) as the interactive UI. However, if you prefer to use your own static frontend (e.g., a custom React/Vite app), you can switch to the `static` driver.
|
|
256
|
+
|
|
257
|
+
Here’s how you can do it:
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
controller:
|
|
261
|
+
type: http-server
|
|
262
|
+
port: 8080
|
|
263
|
+
webui:
|
|
264
|
+
driver: static
|
|
265
|
+
static_dir: webui
|
|
266
|
+
port: 8081
|
|
267
|
+
```
|
|
268
|
+
Your frontend should be a prebuilt static site (e.g., using `vite build`, `next export`, or `react-scripts` build) and placed in the specified `static_dir`.
|
|
269
|
+
Make sure `index.html` exists in that directory.
|
|
270
|
+
|
|
271
|
+
#### 📁 Example Directory Structure
|
|
272
|
+
```
|
|
273
|
+
project/
|
|
274
|
+
├── model-compose.yml
|
|
275
|
+
├── webui/
|
|
276
|
+
│ ├── index.html
|
|
277
|
+
│ ├── assets/
|
|
278
|
+
│ └── ...
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
#### 🔧 Notes
|
|
282
|
+
* Ensure the `static_dir` path is relative to the project root or an absolute path.
|
|
283
|
+
* You can use environment variables inside `model-compose.yml` to make this path configurable.
|
|
284
|
+
|
|
285
|
+
Support for additional drivers (e.g., `dynamic`) may be added in future versions.
|
|
286
|
+
|
|
287
|
+
Once configured, the Web UI will be available at:
|
|
288
|
+
```
|
|
289
|
+
http://localhost:8081
|
|
290
|
+
```
|
|
252
291
|
|
|
253
292
|
---
|
|
254
293
|
## 🛰 MCP Server Support
|
|
@@ -219,7 +219,46 @@ Once enabled, the Web UI will be available at:
|
|
|
219
219
|
```
|
|
220
220
|
http://localhost:8081
|
|
221
221
|
```
|
|
222
|
-
|
|
222
|
+
|
|
223
|
+
## 🎨 Custom Web UI
|
|
224
|
+
You can fully customize the Web UI experience by specifying a different driver or serving your own frontend.
|
|
225
|
+
|
|
226
|
+
By default, `model-compose` uses [Gradio](https://www.gradio.app) as the interactive UI. However, if you prefer to use your own static frontend (e.g., a custom React/Vite app), you can switch to the `static` driver.
|
|
227
|
+
|
|
228
|
+
Here’s how you can do it:
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
controller:
|
|
232
|
+
type: http-server
|
|
233
|
+
port: 8080
|
|
234
|
+
webui:
|
|
235
|
+
driver: static
|
|
236
|
+
static_dir: webui
|
|
237
|
+
port: 8081
|
|
238
|
+
```
|
|
239
|
+
Your frontend should be a prebuilt static site (e.g., using `vite build`, `next export`, or `react-scripts` build) and placed in the specified `static_dir`.
|
|
240
|
+
Make sure `index.html` exists in that directory.
|
|
241
|
+
|
|
242
|
+
#### 📁 Example Directory Structure
|
|
243
|
+
```
|
|
244
|
+
project/
|
|
245
|
+
├── model-compose.yml
|
|
246
|
+
├── webui/
|
|
247
|
+
│ ├── index.html
|
|
248
|
+
│ ├── assets/
|
|
249
|
+
│ └── ...
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
#### 🔧 Notes
|
|
253
|
+
* Ensure the `static_dir` path is relative to the project root or an absolute path.
|
|
254
|
+
* You can use environment variables inside `model-compose.yml` to make this path configurable.
|
|
255
|
+
|
|
256
|
+
Support for additional drivers (e.g., `dynamic`) may be added in future versions.
|
|
257
|
+
|
|
258
|
+
Once configured, the Web UI will be available at:
|
|
259
|
+
```
|
|
260
|
+
http://localhost:8081
|
|
261
|
+
```
|
|
223
262
|
|
|
224
263
|
---
|
|
225
264
|
## 🛰 MCP Server Support
|
|
@@ -11,7 +11,7 @@ from mindor.core.compose import *
|
|
|
11
11
|
@click.option(
|
|
12
12
|
"--file", "-f", "config_files", multiple=True,
|
|
13
13
|
type=click.Path(exists=True, dir_okay=False, path_type=Path),
|
|
14
|
-
help="Compose configuration files"
|
|
14
|
+
help="Compose configuration files"
|
|
15
15
|
)
|
|
16
16
|
@click.pass_context
|
|
17
17
|
def compose_command(ctx: click.Context, config_files: List[Path]) -> None:
|
|
@@ -25,11 +25,11 @@ def compose_command(ctx: click.Context, config_files: List[Path]) -> None:
|
|
|
25
25
|
"--env-file", "env_files", multiple=True,
|
|
26
26
|
type=click.Path(exists=True, dir_okay=False, path_type=Path),
|
|
27
27
|
required=False,
|
|
28
|
-
help="Path to a .env file containing environment variables."
|
|
28
|
+
help="Path to a .env file containing environment variables."
|
|
29
29
|
)
|
|
30
30
|
@click.option(
|
|
31
31
|
"--env", "-e", "env_data", multiple=True,
|
|
32
|
-
help="Environment variable in the form KEY=VALUE. Repeatable."
|
|
32
|
+
help="Environment variable in the form KEY=VALUE. Repeatable."
|
|
33
33
|
)
|
|
34
34
|
@click.option("--verbose", "-v", is_flag=True, help="Enable verbose output.")
|
|
35
35
|
@click.pass_context
|
|
@@ -55,11 +55,11 @@ def up_command(
|
|
|
55
55
|
"--env-file", "env_files", multiple=True,
|
|
56
56
|
type=click.Path(exists=True, dir_okay=False, path_type=Path),
|
|
57
57
|
required=False,
|
|
58
|
-
help="Path to a .env file containing environment variables."
|
|
58
|
+
help="Path to a .env file containing environment variables."
|
|
59
59
|
)
|
|
60
60
|
@click.option(
|
|
61
61
|
"--env", "-e", "env_data", multiple=True,
|
|
62
|
-
help="Environment variable in the form KEY=VALUE. Repeatable."
|
|
62
|
+
help="Environment variable in the form KEY=VALUE. Repeatable."
|
|
63
63
|
)
|
|
64
64
|
@click.option("--verbose", "-v", is_flag=True, help="Enable verbose output.")
|
|
65
65
|
@click.pass_context
|
|
@@ -84,7 +84,7 @@ def down_command(
|
|
|
84
84
|
"--env-file", "env_files", multiple=True,
|
|
85
85
|
type=click.Path(exists=True, dir_okay=False, path_type=Path),
|
|
86
86
|
required=False,
|
|
87
|
-
help="Path to a .env file containing environment variables."
|
|
87
|
+
help="Path to a .env file containing environment variables."
|
|
88
88
|
)
|
|
89
89
|
@click.option(
|
|
90
90
|
"--env", "-e", "env_data", multiple=True,
|
|
@@ -113,11 +113,11 @@ def start_command(
|
|
|
113
113
|
"--env-file", "env_files", multiple=True,
|
|
114
114
|
type=click.Path(exists=True, dir_okay=False, path_type=Path),
|
|
115
115
|
required=False,
|
|
116
|
-
help="Path to a .env file containing environment variables."
|
|
116
|
+
help="Path to a .env file containing environment variables."
|
|
117
117
|
)
|
|
118
118
|
@click.option(
|
|
119
119
|
"--env", "-e", "env_data", multiple=True,
|
|
120
|
-
help="Environment variable in the form KEY=VALUE. Repeatable."
|
|
120
|
+
help="Environment variable in the form KEY=VALUE. Repeatable."
|
|
121
121
|
)
|
|
122
122
|
@click.option("--verbose", "-v", is_flag=True, help="Enable verbose output.")
|
|
123
123
|
@click.pass_context
|
|
@@ -149,11 +149,11 @@ def stop_command(
|
|
|
149
149
|
"--env-file", "env_files", multiple=True,
|
|
150
150
|
type=click.Path(exists=True, dir_okay=False, path_type=Path),
|
|
151
151
|
required=False,
|
|
152
|
-
help="Path to a .env file containing environment variables."
|
|
152
|
+
help="Path to a .env file containing environment variables."
|
|
153
153
|
)
|
|
154
154
|
@click.option(
|
|
155
155
|
"--env", "-e", "env_data", multiple=True,
|
|
156
|
-
help="Environment variable in the form KEY=VALUE. Repeatable."
|
|
156
|
+
help="Environment variable in the form KEY=VALUE. Repeatable."
|
|
157
157
|
)
|
|
158
158
|
@click.option("--verbose", "-v", is_flag=True, help="Enable verbose output.")
|
|
159
159
|
@click.pass_context
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Any
|
|
2
|
-
from mindor.core.utils.
|
|
2
|
+
from mindor.core.utils.renderers import VariableRenderer
|
|
3
3
|
from mindor.core.gateway import find_gateway_by_port
|
|
4
4
|
|
|
5
5
|
class ComponentActionContext:
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from typing import Type, Union, Literal, Optional, Dict, List, Tuple, Set, Annotated, Callable, Any
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
from mindor.dsl.schema.component import ModelComponentConfig, ModelTaskType, DeviceMode
|
|
4
|
+
from mindor.dsl.schema.action import ModelActionConfig
|
|
5
|
+
from mindor.core.services import AsyncService
|
|
6
|
+
from ...context import ComponentActionContext
|
|
7
|
+
from transformers import PreTrainedModel, PreTrainedTokenizer
|
|
8
|
+
import torch
|
|
9
|
+
|
|
10
|
+
class ModelTaskService(AsyncService):
|
|
11
|
+
def __init__(self, id: str, config: ModelComponentConfig, daemon: bool):
|
|
12
|
+
super().__init__(daemon)
|
|
13
|
+
|
|
14
|
+
self.id: str = id
|
|
15
|
+
self.config: ModelComponentConfig = config
|
|
16
|
+
|
|
17
|
+
async def run(self, action: ModelActionConfig, context: ComponentActionContext) -> Any:
|
|
18
|
+
return await self._run(action, context)
|
|
19
|
+
|
|
20
|
+
@abstractmethod
|
|
21
|
+
async def _run(self, action: ModelActionConfig, context: ComponentActionContext) -> Any:
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
def _load_pretrained_model(self, extra_params: Optional[Dict[str, Any]] = None) -> PreTrainedModel:
|
|
25
|
+
params = self._get_common_model_params()
|
|
26
|
+
|
|
27
|
+
if extra_params:
|
|
28
|
+
params.update(extra_params)
|
|
29
|
+
|
|
30
|
+
model = self._get_model_class().from_pretrained(self.config.model, **params)
|
|
31
|
+
|
|
32
|
+
if self.config.device_mode == DeviceMode.SINGLE:
|
|
33
|
+
model = model.to(torch.device(self.config.device))
|
|
34
|
+
|
|
35
|
+
return model
|
|
36
|
+
|
|
37
|
+
def _get_common_model_params(self) -> Dict[str, Any]:
|
|
38
|
+
params: Dict[str, Any] = {}
|
|
39
|
+
|
|
40
|
+
if self.config.device_mode != DeviceMode.SINGLE:
|
|
41
|
+
params["device_map"] = self.config.device_mode.value
|
|
42
|
+
|
|
43
|
+
if self.config.precision is not None:
|
|
44
|
+
params["torch_dtype"] = getattr(torch, self.config.precision.value)
|
|
45
|
+
|
|
46
|
+
if self.config.low_cpu_mem_usage:
|
|
47
|
+
params["low_cpu_mem_usage"] = True
|
|
48
|
+
|
|
49
|
+
if self.config.revision:
|
|
50
|
+
params["revision"] = self.config.revision
|
|
51
|
+
|
|
52
|
+
if self.config.cache_dir:
|
|
53
|
+
params["cache_dir"] = self.config.cache_dir
|
|
54
|
+
|
|
55
|
+
if self.config.local_files_only:
|
|
56
|
+
params["local_files_only"] = True
|
|
57
|
+
|
|
58
|
+
return params
|
|
59
|
+
|
|
60
|
+
def _load_pretrained_tokenizer(self, extra_params: Optional[Dict[str, Any]] = None) -> PreTrainedTokenizer:
|
|
61
|
+
params = self._get_common_tokenizer_params()
|
|
62
|
+
|
|
63
|
+
if extra_params:
|
|
64
|
+
params.update(extra_params)
|
|
65
|
+
|
|
66
|
+
return self._get_tokenizer_class().from_pretrained(self.config.model, **params)
|
|
67
|
+
|
|
68
|
+
def _get_common_tokenizer_params(self) -> Dict[str, Any]:
|
|
69
|
+
params: Dict[str, Any] = {}
|
|
70
|
+
|
|
71
|
+
if not self.config.fast_tokenizer:
|
|
72
|
+
params["use_fast"] = False
|
|
73
|
+
|
|
74
|
+
if self.config.revision:
|
|
75
|
+
params["revision"] = self.config.revision
|
|
76
|
+
|
|
77
|
+
if self.config.cache_dir:
|
|
78
|
+
params["cache_dir"] = self.config.cache_dir
|
|
79
|
+
|
|
80
|
+
if self.config.local_files_only:
|
|
81
|
+
params["local_files_only"] = True
|
|
82
|
+
|
|
83
|
+
return params
|
|
84
|
+
|
|
85
|
+
def _get_model_device(self, model: PreTrainedModel) -> torch.device:
|
|
86
|
+
return next(model.parameters()).device
|
|
87
|
+
|
|
88
|
+
@abstractmethod
|
|
89
|
+
def _get_model_class(self) -> Type[PreTrainedModel]:
|
|
90
|
+
pass
|
|
91
|
+
|
|
92
|
+
@abstractmethod
|
|
93
|
+
def _get_tokenizer_class(self) -> Type[PreTrainedTokenizer]:
|
|
94
|
+
pass
|
|
95
|
+
|
|
96
|
+
def register_model_task_service(type: ModelTaskType):
|
|
97
|
+
def decorator(cls: Type[ModelTaskService]) -> Type[ModelTaskService]:
|
|
98
|
+
ModelTaskServiceRegistry[type] = cls
|
|
99
|
+
return cls
|
|
100
|
+
return decorator
|
|
101
|
+
|
|
102
|
+
ModelTaskServiceRegistry: Dict[ModelTaskType, Type[ModelTaskService]] = {}
|
{model_compose-0.3.2 → model_compose-0.3.3}/src/mindor/core/component/services/model/model.py
RENAMED
|
@@ -25,7 +25,7 @@ class ModelComponent(ComponentService):
|
|
|
25
25
|
from . import tasks
|
|
26
26
|
return ModelTaskServiceRegistry[type](self.id, self.config, self.daemon)
|
|
27
27
|
except KeyError:
|
|
28
|
-
raise ValueError(f"Unsupported
|
|
28
|
+
raise ValueError(f"Unsupported model task type: {type}")
|
|
29
29
|
|
|
30
30
|
async def _serve(self) -> None:
|
|
31
31
|
await self.task_service.start()
|
|
@@ -5,13 +5,15 @@ from mindor.core.logger import logging
|
|
|
5
5
|
from ..base import ModelTaskService, ModelTaskType, register_model_task_service
|
|
6
6
|
from ..base import ComponentActionContext
|
|
7
7
|
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, PreTrainedModel, PreTrainedTokenizer, GenerationMixin
|
|
8
|
+
from torch import Tensor
|
|
8
9
|
import torch
|
|
9
10
|
|
|
10
11
|
class SummarizationTaskAction:
|
|
11
|
-
def __init__(self, config: SummarizationModelActionConfig, model: Union[PreTrainedModel, GenerationMixin], tokenizer: PreTrainedTokenizer):
|
|
12
|
+
def __init__(self, config: SummarizationModelActionConfig, model: Union[PreTrainedModel, GenerationMixin], tokenizer: PreTrainedTokenizer, device: torch.device):
|
|
12
13
|
self.config: SummarizationModelActionConfig = config
|
|
13
14
|
self.model: Union[PreTrainedModel, GenerationMixin] = model
|
|
14
15
|
self.tokenizer: PreTrainedTokenizer = tokenizer
|
|
16
|
+
self.device: torch.device = device
|
|
15
17
|
|
|
16
18
|
async def run(self, context: ComponentActionContext) -> Any:
|
|
17
19
|
text: Union[str, List[str]] = await context.render_variable(self.config.text)
|
|
@@ -30,7 +32,8 @@ class SummarizationTaskAction:
|
|
|
30
32
|
|
|
31
33
|
for index in range(0, len(texts), batch_size):
|
|
32
34
|
batch_texts = texts[index:index + batch_size]
|
|
33
|
-
inputs = self.tokenizer(batch_texts, return_tensors="pt", max_length=max_input_length, padding=True, truncation=True)
|
|
35
|
+
inputs: Dict[str, Tensor] = self.tokenizer(batch_texts, return_tensors="pt", max_length=max_input_length, padding=True, truncation=True)
|
|
36
|
+
inputs = { k: v.to(self.device) for k, v in inputs.items() }
|
|
34
37
|
|
|
35
38
|
with torch.no_grad():
|
|
36
39
|
outputs = self.model.generate(
|
|
@@ -60,12 +63,14 @@ class SummarizationTaskService(ModelTaskService):
|
|
|
60
63
|
|
|
61
64
|
self.model: Optional[Union[PreTrainedModel, GenerationMixin]] = None
|
|
62
65
|
self.tokenizer: Optional[PreTrainedTokenizer] = None
|
|
66
|
+
self.device: Optional[torch.device] = None
|
|
63
67
|
|
|
64
68
|
async def _serve(self) -> None:
|
|
65
69
|
try:
|
|
66
|
-
self.model =
|
|
67
|
-
self.tokenizer =
|
|
68
|
-
|
|
70
|
+
self.model = self._load_pretrained_model()
|
|
71
|
+
self.tokenizer = self._load_pretrained_tokenizer()
|
|
72
|
+
self.device = self._get_model_device(self.model)
|
|
73
|
+
logging.info(f"Model and tokenizer loaded successfully on device '{self.device}': {self.config.model}")
|
|
69
74
|
except Exception as e:
|
|
70
75
|
logging.error(f"Failed to load model '{self.config.model}': {e}")
|
|
71
76
|
raise
|
|
@@ -73,6 +78,13 @@ class SummarizationTaskService(ModelTaskService):
|
|
|
73
78
|
async def _shutdown(self) -> None:
|
|
74
79
|
self.model = None
|
|
75
80
|
self.tokenizer = None
|
|
81
|
+
self.device = None
|
|
76
82
|
|
|
77
83
|
async def _run(self, action: ModelActionConfig, context: ComponentActionContext) -> Any:
|
|
78
|
-
return await SummarizationTaskAction(action, self.model, self.tokenizer).run(context)
|
|
84
|
+
return await SummarizationTaskAction(action, self.model, self.tokenizer, self.device).run(context)
|
|
85
|
+
|
|
86
|
+
def _get_model_class(self) -> Type[PreTrainedModel]:
|
|
87
|
+
return AutoModelForSeq2SeqLM
|
|
88
|
+
|
|
89
|
+
def _get_tokenizer_class(self) -> Type[PreTrainedTokenizer]:
|
|
90
|
+
return AutoTokenizer
|
|
@@ -7,13 +7,15 @@ from ..base import ComponentActionContext
|
|
|
7
7
|
from transformers import AutoModelForSequenceClassification, AutoTokenizer, PreTrainedModel, PreTrainedTokenizer
|
|
8
8
|
from transformers.modeling_outputs import SequenceClassifierOutput
|
|
9
9
|
import torch.nn.functional as F
|
|
10
|
+
from torch import Tensor
|
|
10
11
|
import torch
|
|
11
12
|
|
|
12
13
|
class TextClassificationTaskAction:
|
|
13
|
-
def __init__(self, config: TextClassificationModelActionConfig, model: PreTrainedModel, tokenizer: PreTrainedTokenizer):
|
|
14
|
+
def __init__(self, config: TextClassificationModelActionConfig, model: PreTrainedModel, tokenizer: PreTrainedTokenizer, device: torch.device):
|
|
14
15
|
self.config: TextClassificationModelActionConfig = config
|
|
15
16
|
self.model: PreTrainedModel = model
|
|
16
17
|
self.tokenizer: PreTrainedTokenizer = tokenizer
|
|
18
|
+
self.device: torch.device = device
|
|
17
19
|
|
|
18
20
|
async def run(self, context: ComponentActionContext, labels: Optional[List[str]]) -> Any:
|
|
19
21
|
text: Union[str, List[str]] = await context.render_variable(self.config.text)
|
|
@@ -26,7 +28,8 @@ class TextClassificationTaskAction:
|
|
|
26
28
|
|
|
27
29
|
for index in range(0, len(texts), batch_size):
|
|
28
30
|
batch_texts = texts[index:index + batch_size]
|
|
29
|
-
inputs = self.tokenizer(batch_texts, return_tensors="pt", padding=True, truncation=True)
|
|
31
|
+
inputs: Dict[str, Tensor] = self.tokenizer(batch_texts, return_tensors="pt", padding=True, truncation=True)
|
|
32
|
+
inputs = { k: v.to(self.device) for k, v in inputs.items() }
|
|
30
33
|
|
|
31
34
|
with torch.no_grad():
|
|
32
35
|
outputs: SequenceClassifierOutput = self.model(**inputs)
|
|
@@ -60,12 +63,14 @@ class TextClassificationTaskService(ModelTaskService):
|
|
|
60
63
|
|
|
61
64
|
self.model: Optional[PreTrainedModel] = None
|
|
62
65
|
self.tokenizer: Optional[PreTrainedTokenizer] = None
|
|
66
|
+
self.device: Optional[torch.device] = None
|
|
63
67
|
|
|
64
68
|
async def _serve(self) -> None:
|
|
65
69
|
try:
|
|
66
|
-
self.model =
|
|
67
|
-
self.tokenizer =
|
|
68
|
-
|
|
70
|
+
self.model = self._load_pretrained_model()
|
|
71
|
+
self.tokenizer = self._load_pretrained_tokenizer()
|
|
72
|
+
self.device = self._get_model_device(self.model)
|
|
73
|
+
logging.info(f"Model and tokenizer loaded successfully on device '{self.device}': {self.config.model}")
|
|
69
74
|
except Exception as e:
|
|
70
75
|
logging.error(f"Failed to load model '{self.config.model}': {e}")
|
|
71
76
|
raise
|
|
@@ -73,6 +78,13 @@ class TextClassificationTaskService(ModelTaskService):
|
|
|
73
78
|
async def _shutdown(self) -> None:
|
|
74
79
|
self.model = None
|
|
75
80
|
self.tokenizer = None
|
|
81
|
+
self.device = None
|
|
76
82
|
|
|
77
83
|
async def _run(self, action: ModelActionConfig, context: ComponentActionContext) -> Any:
|
|
78
|
-
return await TextClassificationTaskAction(action, self.model, self.tokenizer).run(context, self.config.labels)
|
|
84
|
+
return await TextClassificationTaskAction(action, self.model, self.tokenizer, self.device).run(context, self.config.labels)
|
|
85
|
+
|
|
86
|
+
def _get_model_class(self) -> Type[PreTrainedModel]:
|
|
87
|
+
return AutoModelForSequenceClassification
|
|
88
|
+
|
|
89
|
+
def _get_tokenizer_class(self) -> Type[PreTrainedTokenizer]:
|
|
90
|
+
return AutoTokenizer
|
|
@@ -10,10 +10,11 @@ from torch import Tensor
|
|
|
10
10
|
import torch
|
|
11
11
|
|
|
12
12
|
class TextEmbeddingTaskAction:
|
|
13
|
-
def __init__(self, config: TextEmbeddingModelActionConfig, model: PreTrainedModel, tokenizer: PreTrainedTokenizer):
|
|
13
|
+
def __init__(self, config: TextEmbeddingModelActionConfig, model: PreTrainedModel, tokenizer: PreTrainedTokenizer, device: torch.device):
|
|
14
14
|
self.config: TextEmbeddingModelActionConfig = config
|
|
15
15
|
self.model: PreTrainedModel = model
|
|
16
16
|
self.tokenizer: PreTrainedTokenizer = tokenizer
|
|
17
|
+
self.device: torch.device = device
|
|
17
18
|
|
|
18
19
|
async def run(self, context: ComponentActionContext) -> Any:
|
|
19
20
|
text: Union[str, List[str]] = await context.render_variable(self.config.text)
|
|
@@ -28,13 +29,14 @@ class TextEmbeddingTaskAction:
|
|
|
28
29
|
|
|
29
30
|
for index in range(0, len(texts), batch_size):
|
|
30
31
|
batch_texts = texts[index:index + batch_size]
|
|
31
|
-
inputs = self.tokenizer(batch_texts, return_tensors="pt", max_length=max_input_length, padding=True, truncation=True)
|
|
32
|
-
|
|
32
|
+
inputs: Dict[str, Tensor] = self.tokenizer(batch_texts, return_tensors="pt", max_length=max_input_length, padding=True, truncation=True)
|
|
33
|
+
inputs = { k: v.to(self.device) for k, v in inputs.items() }
|
|
33
34
|
|
|
34
35
|
with torch.no_grad():
|
|
35
36
|
outputs: BaseModelOutput = self.model(**inputs)
|
|
36
37
|
last_hidden_state = outputs.last_hidden_state # (batch_size, seq_len, hidden_size)
|
|
37
38
|
|
|
39
|
+
attention_mask = inputs.get("attention_mask", None)
|
|
38
40
|
embeddings = self._pool_hidden_state(last_hidden_state, attention_mask, pooling)
|
|
39
41
|
|
|
40
42
|
if normalize:
|
|
@@ -75,12 +77,14 @@ class TextEmbeddingTaskService(ModelTaskService):
|
|
|
75
77
|
|
|
76
78
|
self.model: Optional[PreTrainedModel] = None
|
|
77
79
|
self.tokenizer: Optional[PreTrainedTokenizer] = None
|
|
80
|
+
self.device: Optional[torch.device] = None
|
|
78
81
|
|
|
79
82
|
async def _serve(self) -> None:
|
|
80
83
|
try:
|
|
81
|
-
self.model =
|
|
82
|
-
self.tokenizer =
|
|
83
|
-
|
|
84
|
+
self.model = self._load_pretrained_model()
|
|
85
|
+
self.tokenizer = self._load_pretrained_tokenizer()
|
|
86
|
+
self.device = self._get_model_device(self.model)
|
|
87
|
+
logging.info(f"Model and tokenizer loaded successfully on device '{self.device}': {self.config.model}")
|
|
84
88
|
except Exception as e:
|
|
85
89
|
logging.error(f"Failed to load model '{self.config.model}': {e}")
|
|
86
90
|
raise
|
|
@@ -88,6 +92,13 @@ class TextEmbeddingTaskService(ModelTaskService):
|
|
|
88
92
|
async def _shutdown(self) -> None:
|
|
89
93
|
self.model = None
|
|
90
94
|
self.tokenizer = None
|
|
95
|
+
self.device = None
|
|
91
96
|
|
|
92
97
|
async def _run(self, action: ModelActionConfig, context: ComponentActionContext) -> Any:
|
|
93
|
-
return await TextEmbeddingTaskAction(action, self.model, self.tokenizer).run(context)
|
|
98
|
+
return await TextEmbeddingTaskAction(action, self.model, self.tokenizer, self.device).run(context)
|
|
99
|
+
|
|
100
|
+
def _get_model_class(self) -> Type[PreTrainedModel]:
|
|
101
|
+
return AutoModel
|
|
102
|
+
|
|
103
|
+
def _get_tokenizer_class(self) -> Type[PreTrainedTokenizer]:
|
|
104
|
+
return AutoTokenizer
|
|
@@ -5,13 +5,15 @@ from mindor.core.logger import logging
|
|
|
5
5
|
from ..base import ModelTaskService, ModelTaskType, register_model_task_service
|
|
6
6
|
from ..base import ComponentActionContext
|
|
7
7
|
from transformers import AutoModelForCausalLM, AutoTokenizer, PreTrainedModel, PreTrainedTokenizer, GenerationMixin
|
|
8
|
+
from torch import Tensor
|
|
8
9
|
import torch
|
|
9
10
|
|
|
10
11
|
class TextGenerationTaskAction:
|
|
11
|
-
def __init__(self, config: TextGenerationModelActionConfig, model: Union[PreTrainedModel, GenerationMixin], tokenizer: PreTrainedTokenizer):
|
|
12
|
+
def __init__(self, config: TextGenerationModelActionConfig, model: Union[PreTrainedModel, GenerationMixin], tokenizer: PreTrainedTokenizer, device: torch.device):
|
|
12
13
|
self.config: TextGenerationModelActionConfig = config
|
|
13
14
|
self.model: Union[PreTrainedModel, GenerationMixin] = model
|
|
14
15
|
self.tokenizer: PreTrainedTokenizer = tokenizer
|
|
16
|
+
self.device: torch.device = device
|
|
15
17
|
|
|
16
18
|
async def run(self, context: ComponentActionContext) -> Any:
|
|
17
19
|
prompt: Union[str, List[str]] = await context.render_variable(self.config.prompt)
|
|
@@ -28,7 +30,8 @@ class TextGenerationTaskAction:
|
|
|
28
30
|
|
|
29
31
|
for index in range(0, len(prompts), batch_size):
|
|
30
32
|
batch_prompts = prompts[index:index + batch_size]
|
|
31
|
-
inputs = self.tokenizer(batch_prompts, return_tensors="pt")
|
|
33
|
+
inputs: Dict[str, Tensor] = self.tokenizer(batch_prompts, return_tensors="pt", padding=True, truncation=True)
|
|
34
|
+
inputs = { k: v.to(self.device) for k, v in inputs.items() }
|
|
32
35
|
|
|
33
36
|
with torch.no_grad():
|
|
34
37
|
outputs = self.model.generate(
|
|
@@ -56,12 +59,14 @@ class TextGenerationTaskService(ModelTaskService):
|
|
|
56
59
|
|
|
57
60
|
self.model: Optional[Union[PreTrainedModel, GenerationMixin]] = None
|
|
58
61
|
self.tokenizer: Optional[PreTrainedTokenizer] = None
|
|
62
|
+
self.device: Optional[torch.device] = None
|
|
59
63
|
|
|
60
64
|
async def _serve(self) -> None:
|
|
61
65
|
try:
|
|
62
|
-
self.model =
|
|
63
|
-
self.tokenizer =
|
|
64
|
-
|
|
66
|
+
self.model = self._load_pretrained_model()
|
|
67
|
+
self.tokenizer = self._load_pretrained_tokenizer()
|
|
68
|
+
self.device = self._get_model_device(self.model)
|
|
69
|
+
logging.info(f"Model and tokenizer loaded successfully on device '{self.device}': {self.config.model}")
|
|
65
70
|
except Exception as e:
|
|
66
71
|
logging.error(f"Failed to load model '{self.config.model}': {e}")
|
|
67
72
|
raise
|
|
@@ -69,6 +74,13 @@ class TextGenerationTaskService(ModelTaskService):
|
|
|
69
74
|
async def _shutdown(self) -> None:
|
|
70
75
|
self.model = None
|
|
71
76
|
self.tokenizer = None
|
|
77
|
+
self.device = None
|
|
72
78
|
|
|
73
79
|
async def _run(self, action: ModelActionConfig, context: ComponentActionContext) -> Any:
|
|
74
|
-
return await TextGenerationTaskAction(action, self.model, self.tokenizer).run(context)
|
|
80
|
+
return await TextGenerationTaskAction(action, self.model, self.tokenizer, self.device).run(context)
|
|
81
|
+
|
|
82
|
+
def _get_model_class(self) -> Type[PreTrainedModel]:
|
|
83
|
+
return AutoModelForCausalLM
|
|
84
|
+
|
|
85
|
+
def _get_tokenizer_class(self) -> Type[PreTrainedTokenizer]:
|
|
86
|
+
return AutoTokenizer
|
|
@@ -5,13 +5,15 @@ from mindor.core.logger import logging
|
|
|
5
5
|
from ..base import ModelTaskService, ModelTaskType, register_model_task_service
|
|
6
6
|
from ..base import ComponentActionContext
|
|
7
7
|
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, PreTrainedModel, PreTrainedTokenizer, GenerationMixin
|
|
8
|
+
from torch import Tensor
|
|
8
9
|
import torch
|
|
9
10
|
|
|
10
11
|
class TranslationTaskAction:
|
|
11
|
-
def __init__(self, config: TranslationModelActionConfig, model: Union[PreTrainedModel, GenerationMixin], tokenizer: PreTrainedTokenizer):
|
|
12
|
+
def __init__(self, config: TranslationModelActionConfig, model: Union[PreTrainedModel, GenerationMixin], tokenizer: PreTrainedTokenizer, device: torch.device):
|
|
12
13
|
self.config: TranslationModelActionConfig = config
|
|
13
14
|
self.model: Union[PreTrainedModel, GenerationMixin] = model
|
|
14
15
|
self.tokenizer: PreTrainedTokenizer = tokenizer
|
|
16
|
+
self.device: torch.device = device
|
|
15
17
|
|
|
16
18
|
async def run(self, context: ComponentActionContext) -> Any:
|
|
17
19
|
text: Union[str, List[str]] = await context.render_variable(self.config.text)
|
|
@@ -28,8 +30,9 @@ class TranslationTaskAction:
|
|
|
28
30
|
|
|
29
31
|
for index in range(0, len(texts), batch_size):
|
|
30
32
|
batch_texts = texts[index:index + batch_size]
|
|
31
|
-
inputs = self.tokenizer(batch_texts, return_tensors="pt", max_length=max_input_length, padding=True, truncation=True)
|
|
32
|
-
|
|
33
|
+
inputs: Dict[str, Tensor] = self.tokenizer(batch_texts, return_tensors="pt", max_length=max_input_length, padding=True, truncation=True)
|
|
34
|
+
inputs = { k: v.to(self.device) for k, v in inputs.items() }
|
|
35
|
+
|
|
33
36
|
with torch.no_grad():
|
|
34
37
|
outputs = self.model.generate(
|
|
35
38
|
**inputs,
|
|
@@ -57,12 +60,14 @@ class TranslationTaskService(ModelTaskService):
|
|
|
57
60
|
|
|
58
61
|
self.model: Optional[Union[PreTrainedModel, GenerationMixin]] = None
|
|
59
62
|
self.tokenizer: Optional[PreTrainedTokenizer] = None
|
|
63
|
+
self.device: Optional[torch.device] = None
|
|
60
64
|
|
|
61
65
|
async def _serve(self) -> None:
|
|
62
66
|
try:
|
|
63
|
-
self.model =
|
|
64
|
-
self.tokenizer =
|
|
65
|
-
|
|
67
|
+
self.model = self._load_pretrained_model()
|
|
68
|
+
self.tokenizer = self._load_pretrained_tokenizer()
|
|
69
|
+
self.device = self._get_model_device(self.model)
|
|
70
|
+
logging.info(f"Model and tokenizer loaded successfully on device '{self.device}': {self.config.model}")
|
|
66
71
|
except Exception as e:
|
|
67
72
|
logging.error(f"Failed to load model '{self.config.model}': {e}")
|
|
68
73
|
raise
|
|
@@ -70,6 +75,13 @@ class TranslationTaskService(ModelTaskService):
|
|
|
70
75
|
async def _shutdown(self) -> None:
|
|
71
76
|
self.model = None
|
|
72
77
|
self.tokenizer = None
|
|
78
|
+
self.device = None
|
|
73
79
|
|
|
74
80
|
async def _run(self, action: ModelActionConfig, context: ComponentActionContext) -> Any:
|
|
75
|
-
return await TranslationTaskAction(action, self.model, self.tokenizer).run(context)
|
|
81
|
+
return await TranslationTaskAction(action, self.model, self.tokenizer, self.device).run(context)
|
|
82
|
+
|
|
83
|
+
def _get_model_class(self) -> Type[PreTrainedModel]:
|
|
84
|
+
return AutoModelForSeq2SeqLM
|
|
85
|
+
|
|
86
|
+
def _get_tokenizer_class(self) -> Type[PreTrainedTokenizer]:
|
|
87
|
+
return AutoTokenizer
|
|
@@ -17,7 +17,7 @@ from mindor.core.workflow import Workflow, WorkflowResolver, create_workflow
|
|
|
17
17
|
from mindor.core.logger import LoggerService, create_logger
|
|
18
18
|
from mindor.core.controller.webui import ControllerWebUI
|
|
19
19
|
from mindor.core.utils.workqueue import WorkQueue
|
|
20
|
-
from mindor.core.utils.
|
|
20
|
+
from mindor.core.utils.caching import ExpiringDict
|
|
21
21
|
from .runtime.specs import ControllerRuntimeSpecs
|
|
22
22
|
from .runtime.docker import DockerRuntimeLauncher
|
|
23
23
|
from threading import Lock
|