From bffd7adc43dfa92c355042490840b5ab72a3cf80 Mon Sep 17 00:00:00 2001 From: wangzhihong Date: Tue, 31 Mar 2026 15:50:54 +0800 Subject: [PATCH 1/3] reface the interface of online models --- lazyllm/module/llms/automodel.py | 6 ++- lazyllm/module/llms/online_module.py | 5 +-- .../onlinemodule/base/onlineChatModuleBase.py | 9 +++-- .../base/onlineEmbeddingModuleBase.py | 10 +++-- .../onlinemodule/base/onlineMultiModalBase.py | 23 +++++------- .../module/llms/onlinemodule/base/utils.py | 27 ++++++++++++++ lazyllm/module/llms/onlinemodule/chat.py | 19 ++++++---- .../llms/onlinemodule/dynamic_router.py | 8 ++-- lazyllm/module/llms/onlinemodule/embedding.py | 34 +++++++++++------ .../module/llms/onlinemodule/multimodal.py | 37 ++++++++++++------- 10 files changed, 116 insertions(+), 62 deletions(-) diff --git a/lazyllm/module/llms/automodel.py b/lazyllm/module/llms/automodel.py index da85dcc20..1ea3c0e0e 100644 --- a/lazyllm/module/llms/automodel.py +++ b/lazyllm/module/llms/automodel.py @@ -11,8 +11,12 @@ class AutoModel: def __new__(cls, model: Optional[str] = None, *, config_id: Optional[str] = None, source: Optional[str] = None, # noqa C901 type: Optional[str] = None, config: Union[str, bool] = True, **kwargs: Any): # check and accomodate user params - model = model or kwargs.pop('base_model', kwargs.pop('embed_model_name', None)) + model = model or kwargs.pop('base_model', kwargs.pop('embed_model_name', kwargs.pop('model_name', None))) if model in lazyllm.online.chat: + if source is not None: + raise ValueError( + f'`{model!r}` is a recognised source name; pass it as `source=` and ' + f'do not also set `source={source!r}`.') source, model = model, None if not model: diff --git a/lazyllm/module/llms/online_module.py b/lazyllm/module/llms/online_module.py index dad906ccd..1ef9c28a8 100644 --- a/lazyllm/module/llms/online_module.py +++ b/lazyllm/module/llms/online_module.py @@ -36,10 +36,7 @@ def __new__(self, model: Optional[str] = None, source: Optional[str] = None, *, embed_kwargs = params.copy() embed_kwargs.pop('function', None) embed_kwargs.setdefault('type', 'rerank' if resolved_type == LLMType.RERANK else 'embed') - return OnlineEmbeddingModule(source=source, - embed_url=url, - embed_model_name=model, - **embed_kwargs) + return OnlineEmbeddingModule(model=model, source=source, url=url, **embed_kwargs) if resolved_type in list(self._MULTI_TYPE_TO_FUNCTION.keys()): multi_kwargs = params.copy() diff --git a/lazyllm/module/llms/onlinemodule/base/onlineChatModuleBase.py b/lazyllm/module/llms/onlinemodule/base/onlineChatModuleBase.py index 49b1ff64e..26254242b 100644 --- a/lazyllm/module/llms/onlinemodule/base/onlineChatModuleBase.py +++ b/lazyllm/module/llms/onlinemodule/base/onlineChatModuleBase.py @@ -14,7 +14,7 @@ from lazyllm.components.utils.file_operate import _delete_old_files, _image_to_base64 from lazyllm.components.utils.downloader.model_downloader import LLMType from ....servermodule import LLMBase, StaticParams -from .utils import LazyLLMOnlineBase +from .utils import LazyLLMOnlineBase, resolve_online_params class LazyLLMOnlineChatModuleBase(LazyLLMOnlineBase, LLMBase): TRAINABLE_MODEL_LIST = [] @@ -126,9 +126,10 @@ def forward(self, __input: Union[Dict, str] = None, *, llm_chat_history: List[Li # TODO(dengyuang): if current forward set stream_output = False but self._stream = True, will use stream = True stream_output = stream_output or self._stream __input, files = self._get_files(__input, lazyllm_files) - runtime_base_url = url or kw.pop('base_url', None) - runtime_url = self._get_chat_url(runtime_base_url) if runtime_base_url else self._chat_url - runtime_model = model or kw.pop('model_name', None) or self._model_name + model, _, url, kw = resolve_online_params(model, None, url, kw, + model_aliases='model_name', url_aliases='base_url') + runtime_url = self._get_chat_url(url) if url else self._chat_url + runtime_model = model or self._model_name params = {'input': __input, 'history': llm_chat_history, 'return_dict': True} if tools: params['tools'] = tools diff --git a/lazyllm/module/llms/onlinemodule/base/onlineEmbeddingModuleBase.py b/lazyllm/module/llms/onlinemodule/base/onlineEmbeddingModuleBase.py index 6c3905aa8..d8a7e5a0e 100644 --- a/lazyllm/module/llms/onlinemodule/base/onlineEmbeddingModuleBase.py +++ b/lazyllm/module/llms/onlinemodule/base/onlineEmbeddingModuleBase.py @@ -3,7 +3,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed, wait from lazyllm import LOG from lazyllm.components.utils.downloader.model_downloader import LLMType -from .utils import LazyLLMOnlineBase +from .utils import LazyLLMOnlineBase, resolve_online_params from lazyllm.components.utils.downloader import ModelManager @@ -41,8 +41,12 @@ def batch_size(self, value: int): def forward(self, input: Union[List, str], url: str = None, model: str = None, **kwargs ) -> Union[List[float], List[List[float]]]: - runtime_url = url or kwargs.pop('base_url', kwargs.pop('embed_url', None)) or self._embed_url - runtime_model = model or kwargs.pop('model_name', kwargs.pop('embed_model_name', None)) or self._embed_model_name + model, _, url, kwargs = resolve_online_params( + model, None, url, kwargs, + model_aliases=('model_name', 'embed_model_name', 'embed_name'), + url_aliases=('base_url', 'embed_url')) + runtime_url = url or self._embed_url + runtime_model = model or self._embed_model_name if runtime_model is not None: kwargs['model'] = runtime_model diff --git a/lazyllm/module/llms/onlinemodule/base/onlineMultiModalBase.py b/lazyllm/module/llms/onlinemodule/base/onlineMultiModalBase.py index 31b8c4af3..8dfb33966 100644 --- a/lazyllm/module/llms/onlinemodule/base/onlineMultiModalBase.py +++ b/lazyllm/module/llms/onlinemodule/base/onlineMultiModalBase.py @@ -1,7 +1,7 @@ from typing import List, Dict, Union, Optional import lazyllm from ....servermodule import LLMBase -from .utils import LazyLLMOnlineBase +from .utils import LazyLLMOnlineBase, resolve_online_params import base64 from pathlib import Path import requests @@ -29,23 +29,18 @@ def type(self): return 'MultiModal' def _forward(self, input: Union[Dict, str] = None, files: List[str] = None, **kwargs): - '''Forward method to be implemented by subclasses''' raise NotImplementedError(f'Subclass {self.__class__.__name__} must implement this method') def forward(self, input: Union[Dict, str] = None, *, lazyllm_files=None, url: str = None, model: str = None, **kwargs): - '''Main forward method with file handling''' - try: - input, files = self._get_files(input, lazyllm_files or kwargs.pop('files', None)) - runtime_url = url or kwargs.pop('base_url', None) or self._base_url - runtime_model = model or kwargs.pop('model_name', None) or self._model_name - call_params = {'input': input, **kwargs} - if files: call_params['files'] = files - return self._forward(**call_params, model=runtime_model, url=runtime_url) - - except Exception as e: - lazyllm.LOG.error(f'Error in {self.__class__.__name__}.forward: {str(e)}') - raise + input, files = self._get_files(input, lazyllm_files or kwargs.pop('files', None)) + model, _, url, kwargs = resolve_online_params(model, None, url, kwargs, + model_aliases='model_name', url_aliases='base_url') + runtime_url = url or self._base_url + runtime_model = model or self._model_name + call_params = {'input': input, **kwargs} + if files: call_params['files'] = files + return self._forward(**call_params, model=runtime_model, url=runtime_url) def __repr__(self): return lazyllm.make_repr('Module', 'OnlineMultiModalModule', diff --git a/lazyllm/module/llms/onlinemodule/base/utils.py b/lazyllm/module/llms/onlinemodule/base/utils.py index 063a06ef2..67a446e21 100644 --- a/lazyllm/module/llms/onlinemodule/base/utils.py +++ b/lazyllm/module/llms/onlinemodule/base/utils.py @@ -31,6 +31,33 @@ def select_source_with_default_key(available_models, explicit_source: Optional[s f'You can set one of those environment: {excepted}') +def resolve_online_params( + model: Optional[str], source: Optional[str], url: Optional[str], extra: dict, + *, model_aliases: Union[str, tuple] = (), url_aliases: Union[str, tuple] = (), source_registry=None, +) -> tuple: + if isinstance(model_aliases, str): model_aliases = (model_aliases,) + if isinstance(url_aliases, str): url_aliases = (url_aliases,) + remaining = dict(extra) + for alias in model_aliases: + if (val := remaining.pop(alias, None)) is not None: + if model is not None: + raise ValueError(f'Conflicting parameters: `model` and `{alias}` are both provided. Use `model` only.') + model = val + for alias in url_aliases: + if (val := remaining.pop(alias, None)) is not None: + if url is not None: + raise ValueError(f'Conflicting parameters: `url` and `{alias}` are both provided. Use `url` only.') + url = val + if source_registry is not None and model is not None: + _in = (lambda x: x in source_registry) if hasattr(source_registry, '__contains__') else source_registry + if _in(model): + if source is not None and _in(source): + raise ValueError(f'`{model!r}` and `{source!r}` are both recognised source names; ' + f'provide exactly one via `source=`.') + source, model = model, source + return model, source, url, remaining + + def check_and_add_config(key, description, cfg=config): if key.lower() not in config.get_all_configs(): cfg.add(key, str, '', f'{key.upper()}', description=description) diff --git a/lazyllm/module/llms/onlinemodule/chat.py b/lazyllm/module/llms/onlinemodule/chat.py index b9047c631..d59a1f622 100644 --- a/lazyllm/module/llms/onlinemodule/chat.py +++ b/lazyllm/module/llms/onlinemodule/chat.py @@ -5,7 +5,7 @@ from ...servermodule import LLMBase, StaticParams from .base import OnlineChatModuleBase -from .base.utils import select_source_with_default_key +from .base.utils import select_source_with_default_key, resolve_online_params from .dynamic_router import _DynamicSourceRouterMixin, dynamic_model_config_context @@ -32,11 +32,12 @@ class OnlineChatModule(_DynamicSourceRouterMixin, LLMBase, metaclass=_ChatModule _dynamic_module_slot = 'chat' _dynamic_source_error = 'No source is configured for dynamic LLM source.' - def __new__(cls, model: str = None, source: str = None, base_url: str = None, stream: bool = True, + def __new__(cls, model: str = None, source: str = None, url: str = None, stream: bool = True, return_trace: bool = False, skip_auth: bool = False, type: Optional[str] = None, api_key: str = None, static_params: Optional[StaticParams] = None, id: Optional[str] = None, name: Optional[str] = None, group_id: Optional[str] = None, dynamic_auth: bool = False, **kwargs): - if model in lazyllm.online.chat and source is None: source, model = model, source + model, source, url, kwargs = resolve_online_params( + model, source, url, kwargs, url_aliases='base_url', source_registry=lazyllm.online.chat) if cls._should_use_dynamic(source, dynamic_auth, skip_auth): return super().__new__(cls) @@ -44,23 +45,25 @@ def __new__(cls, model: str = None, source: str = None, base_url: str = None, st raise ValueError('No source is given but an api_key is provided.') source, default_key = select_source_with_default_key(lazyllm.online.chat, source, LLMType.CHAT) api_key = api_key if api_key is not None else default_key - if skip_auth and not base_url: - raise KeyError('base_url must be set for local serving.') + if skip_auth and not url: + raise ValueError('url must be set for local serving.') type = cls._resolve_type_name(type, model, options=[LLMType.LLM, LLMType.CHAT, LLMType.VLM]) return getattr(lazyllm.online.chat, source)( - base_url=base_url, model=model, stream=stream, return_trace=return_trace, + base_url=url, model=model, stream=stream, return_trace=return_trace, api_key=api_key, skip_auth=skip_auth, type=type, **kwargs) - def __init__(self, model: str = None, source: str = None, base_url: str = None, stream: bool = True, + def __init__(self, model: str = None, source: str = None, url: str = None, stream: bool = True, return_trace: bool = False, skip_auth: bool = False, type: Optional[str] = None, api_key: str = None, static_params: Optional[StaticParams] = None, id: Optional[str] = None, name: Optional[str] = None, group_id: Optional[str] = None, dynamic_auth: bool = False, **kwargs): + model, source, url, kwargs = resolve_online_params( + model, source, url, kwargs, url_aliases='base_url', source_registry=lazyllm.online.chat) normalized_type = self._resolve_type_name(type, model, options=[LLMType.LLM, LLMType.CHAT, LLMType.VLM]) _DynamicSourceRouterMixin.__init__(self, id=id, name=name, group_id=group_id, return_trace=return_trace) LLMBase.__init__(self, stream=stream, type=normalized_type, static_params=static_params) self._kwargs = kwargs - self._base_url = base_url + self._base_url = url self._model_name = model self._skip_auth = skip_auth self._init_dynamic_auth(api_key, dynamic_auth) diff --git a/lazyllm/module/llms/onlinemodule/dynamic_router.py b/lazyllm/module/llms/onlinemodule/dynamic_router.py index a6584a8c2..6ab376129 100644 --- a/lazyllm/module/llms/onlinemodule/dynamic_router.py +++ b/lazyllm/module/llms/onlinemodule/dynamic_router.py @@ -68,14 +68,16 @@ def _get_supplier(self): self._suppliers[supplier_key] = self._build_supplier(source, skip_auth) return self._suppliers[supplier_key] + _URL_ALIASES = frozenset(('base_url', 'embed_url')) + _MODEL_ALIASES = frozenset(('model_name', 'embed_model_name', 'embed_name')) + def _merge_dynamic_forward_kwargs(self, kwargs: Dict[str, Any]) -> Dict[str, Any]: bucket = self.__class__._get_dynamic_bucket() if not bucket: return kwargs out = dict(kwargs) - if 'url' not in out and 'base_url' not in out: + if 'url' not in out and not (self._URL_ALIASES & out.keys()): if (u := bucket.get('url')) is not None: out['url'] = u - if ('model' not in out and 'model_name' not in out - and 'embed_model_name' not in out): + if 'model' not in out and not (self._MODEL_ALIASES & out.keys()): if (m := bucket.get('model')) is not None: out['model'] = m return out diff --git a/lazyllm/module/llms/onlinemodule/embedding.py b/lazyllm/module/llms/onlinemodule/embedding.py index d7d619efa..846027683 100644 --- a/lazyllm/module/llms/onlinemodule/embedding.py +++ b/lazyllm/module/llms/onlinemodule/embedding.py @@ -4,7 +4,7 @@ from lazyllm.components.utils.downloader.model_downloader import LLMType from lazyllm.common.bind import _MetaBind from .base import OnlineEmbeddingModuleBase -from .base.utils import select_source_with_default_key +from .base.utils import select_source_with_default_key, resolve_online_params from .supplier.doubao import DoubaoEmbed, DoubaoMultimodalEmbed from .map_model_type import get_model_type from .dynamic_router import _DynamicSourceRouterMixin, dynamic_model_config_context @@ -52,15 +52,23 @@ def _create_supplier(source: str, type_name: str, embed_model_name: str, params: return getattr(lazyllm.online.rerank, source)(**params) raise ValueError('Unknown type of online embedding module.') - def __new__(cls, source: str = None, embed_url: str = None, embed_model_name: str = None, + @staticmethod + def _is_embed_source(name: str) -> bool: + return name in lazyllm.online.embed or name in lazyllm.online.rerank + + def __new__(cls, model: str = None, source: str = None, url: str = None, return_trace: bool = False, api_key: str = None, dynamic_auth: bool = False, skip_auth: bool = False, id: Optional[str] = None, name: Optional[str] = None, group_id: Optional[str] = None, type: Optional[str] = None, batch_size: int = 32, **kwargs): + model, source, url, kwargs = resolve_online_params( + model, source, url, kwargs, + model_aliases=('embed_model_name', 'model_name'), url_aliases=('embed_url', 'base_url'), + source_registry=OnlineEmbeddingModule._is_embed_source) if cls._should_use_dynamic(source, dynamic_auth, skip_auth): return super().__new__(cls) if source is None and api_key is not None: raise ValueError('No source is given but an api_key is provided.') - type_name = OnlineEmbeddingModule._resolve_type_name(type, embed_model_name) + type_name = OnlineEmbeddingModule._resolve_type_name(type, model) if type_name == 'embed': source, default_key = select_source_with_default_key(lazyllm.online.embed, source, LLMType.EMBED) elif type_name == 'rerank': @@ -68,20 +76,24 @@ def __new__(cls, source: str = None, embed_url: str = None, embed_model_name: st else: raise ValueError('Unknown type of online embedding module.') api_key = api_key if api_key is not None else default_key - if skip_auth and not embed_url: - raise KeyError('embed_url must be set for local serving.') - params = {'embed_url': embed_url, 'embed_model_name': embed_model_name, 'return_trace': return_trace, + if skip_auth and not url: + raise ValueError('url must be set for local serving.') + params = {'embed_url': url, 'embed_model_name': model, 'return_trace': return_trace, 'batch_size': batch_size, 'api_key': api_key, 'skip_auth': skip_auth, **kwargs} - return OnlineEmbeddingModule._create_supplier(source, type_name, embed_model_name, params) + return OnlineEmbeddingModule._create_supplier(source, type_name, model, params) - def __init__(self, source: str = None, embed_url: str = None, embed_model_name: str = None, + def __init__(self, model: str = None, source: str = None, url: str = None, return_trace: bool = False, api_key: str = None, dynamic_auth: bool = False, skip_auth: bool = False, id: Optional[str] = None, name: Optional[str] = None, group_id: Optional[str] = None, type: Optional[str] = None, batch_size: int = 32, **kwargs): + model, source, url, kwargs = resolve_online_params( + model, source, url, kwargs, + model_aliases=('embed_model_name', 'model_name'), url_aliases=('embed_url', 'base_url'), + source_registry=OnlineEmbeddingModule._is_embed_source) _DynamicSourceRouterMixin.__init__(self, id=id, name=name, group_id=group_id, return_trace=return_trace) - self._embed_url = embed_url - self._embed_model_name = embed_model_name - self._type = type + self._embed_url = url + self._embed_model_name = model + self._type = OnlineEmbeddingModule._resolve_type_name(type, model) self._skip_auth = skip_auth self._kwargs = kwargs self._batch_size = batch_size diff --git a/lazyllm/module/llms/onlinemodule/multimodal.py b/lazyllm/module/llms/onlinemodule/multimodal.py index df5911c30..64ff3f9e0 100644 --- a/lazyllm/module/llms/onlinemodule/multimodal.py +++ b/lazyllm/module/llms/onlinemodule/multimodal.py @@ -3,7 +3,7 @@ from typing import Any, ContextManager, List, Optional, Union from lazyllm.common.bind import _MetaBind from .base import OnlineMultiModalBase -from .base.utils import select_source_with_default_key +from .base.utils import select_source_with_default_key, resolve_online_params from .map_model_type import get_model_type from .dynamic_router import _DynamicSourceRouterMixin, dynamic_model_config_context @@ -44,35 +44,42 @@ def _resolve_type_name(type_name: Optional[str], model: Optional[str]) -> str: resolved = get_model_type(model) if model else None if resolved == 'sd': return 'text2image' - assert resolved in OnlineMultiModalModule.TYPE_GROUP_MAP, 'type must be provided for OnlineMultiModalModule.' + if resolved not in OnlineMultiModalModule.TYPE_GROUP_MAP: + raise ValueError( + f'Cannot infer multimodal type from model {model!r}. ' + f'Please provide `type` explicitly (one of: {list(OnlineMultiModalModule.TYPE_GROUP_MAP.keys())}).') return resolved @staticmethod - def _validate_parameters(source: Optional[str], model: Optional[str], type: str, base_url: Optional[str], + def _validate_parameters(source: Optional[str], model: Optional[str], type: str, url: Optional[str], skip_auth: bool = False, **kwargs) -> tuple: - assert type in OnlineMultiModalModule.TYPE_GROUP_MAP, f'Invalid type: {type}' - if model in lazyllm.online[type] and source is None: - source, model = model, source + if type not in OnlineMultiModalModule.TYPE_GROUP_MAP: + raise ValueError( + f'Invalid type: {type!r}. Must be one of: {list(OnlineMultiModalModule.TYPE_GROUP_MAP.keys())}') register_type = OnlineMultiModalModule.TYPE_GROUP_MAP.get(type).lower() + model, source, url, kwargs = resolve_online_params( + model, source, url, kwargs, source_registry=lazyllm.online[register_type]) source, default_key = select_source_with_default_key(lazyllm.online[register_type], source, type) if default_key and not kwargs.get('api_key'): kwargs['api_key'] = default_key - if skip_auth and not base_url: - raise KeyError('base_url must be set for local serving.') + if skip_auth and not url: + raise ValueError('url must be set for local serving.') default_module_cls = getattr(lazyllm.online[register_type], source) default_model_name = getattr(default_module_cls, 'IMAGE_EDITING_MODEL_NAME' if type == 'image_editing' else 'MODEL_NAME', None) if model is None and default_model_name: model = default_model_name lazyllm.LOG.info(f'For type {type}, source {source}. Automatically selected default model: {model}') - if base_url is not None: - kwargs['base_url'] = base_url + if url is not None: + kwargs['base_url'] = url return source, model, kwargs - def __new__(cls, model: str = None, source: str = None, type: str = None, base_url: str = None, + def __new__(cls, model: str = None, source: str = None, url: str = None, type: str = None, return_trace: bool = False, api_key: str = None, dynamic_auth: bool = False, skip_auth: bool = False, id: Optional[str] = None, name: Optional[str] = None, group_id: Optional[str] = None, **kwargs): + model, source, url, kwargs = resolve_online_params( + model, source, url, kwargs, url_aliases='base_url') if cls._should_use_dynamic(source, dynamic_auth, skip_auth): return super().__new__(cls) if source is None and api_key is not None: @@ -82,7 +89,7 @@ def __new__(cls, model: str = None, source: str = None, type: str = None, base_u type = OnlineMultiModalModule._resolve_type_name( type if type is not None else kwargs.pop('function', None), model) source, model, kwargs_normalized = OnlineMultiModalModule._validate_parameters( - source=source, model=model, type=type, base_url=base_url, skip_auth=skip_auth, **kwargs) + source=source, model=model, type=type, url=url, skip_auth=skip_auth, **kwargs) params = {'return_trace': return_trace, 'type': type} if model is not None: params['model'] = model @@ -90,13 +97,15 @@ def __new__(cls, model: str = None, source: str = None, type: str = None, base_u register_type = OnlineMultiModalModule.TYPE_GROUP_MAP.get(type).lower() return getattr(lazyllm.online[register_type], source)(**params) - def __init__(self, model: str = None, source: str = None, type: str = None, base_url: str = None, + def __init__(self, model: str = None, source: str = None, url: str = None, type: str = None, return_trace: bool = False, api_key: str = None, dynamic_auth: bool = False, skip_auth: bool = False, id: Optional[str] = None, name: Optional[str] = None, group_id: Optional[str] = None, **kwargs): + model, source, url, kwargs = resolve_online_params( + model, source, url, kwargs, url_aliases='base_url') _DynamicSourceRouterMixin.__init__(self, id=id, name=name, group_id=group_id, return_trace=return_trace) self._model_name = model - self._base_url = base_url + self._base_url = url self._skip_auth = skip_auth self._type = self._resolve_type_name(type, model) self._kwargs = kwargs From fe4ba545b357b0d1720bdb5aa3cd56c43786ff06 Mon Sep 17 00:00:00 2001 From: wangzhihong Date: Tue, 31 Mar 2026 16:00:12 +0800 Subject: [PATCH 2/3] reface the interface of online models --- lazyllm/module/llms/onlinemodule/base/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lazyllm/module/llms/onlinemodule/base/utils.py b/lazyllm/module/llms/onlinemodule/base/utils.py index 67a446e21..7f3dbe264 100644 --- a/lazyllm/module/llms/onlinemodule/base/utils.py +++ b/lazyllm/module/llms/onlinemodule/base/utils.py @@ -51,9 +51,9 @@ def resolve_online_params( if source_registry is not None and model is not None: _in = (lambda x: x in source_registry) if hasattr(source_registry, '__contains__') else source_registry if _in(model): - if source is not None and _in(source): - raise ValueError(f'`{model!r}` and `{source!r}` are both recognised source names; ' - f'provide exactly one via `source=`.') + if source is not None and (_in(source) or source == 'dynamic'): + raise ValueError(f'`{model!r}` is a recognised source name; ' + f'do not also provide `source={source!r}`.') source, model = model, source return model, source, url, remaining From b099a05becc231ded80598df47bdd8e6de73f330 Mon Sep 17 00:00:00 2001 From: wangzhihong Date: Tue, 31 Mar 2026 16:34:15 +0800 Subject: [PATCH 3/3] add docs --- lazyllm/docs/module.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/lazyllm/docs/module.py b/lazyllm/docs/module.py index 645aaeda8..a49099277 100644 --- a/lazyllm/docs/module.py +++ b/lazyllm/docs/module.py @@ -1458,7 +1458,7 @@ source (Optional[str]): 使用的服务提供方。为在线模块(``OnlineModule``)指定 ``qwen`` / ``glm`` / ``openai`` 等;若设为 ``local`` 则强制创建本地 TrainableModule。 type (Optional[str]): 模型类型。若未指定会尝试从 kwargs 中获取或由在线模块自动推断。 config (Union[str, bool]): 是否启用 ``auto_model_config_map`` 的覆盖逻辑,或者用户指定的 config 文件路径。默认为 True。 - **kwargs: 兼容 `model` 的同义字段 `base_model` 和 `embed_model_name`,不接收其他用户传入的字段。 + **kwargs: 仅接受 `model` 的同义字段 `base_model`、`embed_model_name` 和 `model_name`,不接收其他用户自定义字段。其他模型参数(如 ``stream``、``type``、``url`` 等)应在配置文件(``auto_model_config_map``)中指定,由 ``config_id`` 引用后自动注入。 ''') add_english_doc('AutoModel', '''\ @@ -1472,7 +1472,7 @@ source (Optional[str]): Provider for online modules (``qwen`` / ``glm`` / ``openai``). Set to ``local`` to force a local TrainableModule. type (Optional[str]): Model type. If omitted, it will try to fetch from kwargs or be inferred by the online module. config (Union[str, bool]): Whether to enable overrides from ``auto_model_config_map``, or a user-specified config file path. Defaults to True. - **kwargs: Accepts `base_model` and `embed_model_name` as synonyms for `model`; does not accept other user-provided fields. + **kwargs: Only the synonyms `base_model`, `embed_model_name` and `model_name` for `model` are accepted; no other user-supplied fields are allowed. Other model parameters (e.g. ``stream``, ``type``, ``url``) should be specified in the configuration file (``auto_model_config_map``) and referenced via ``config_id`` so they are injected automatically. ''') add_chinese_doc('OnlineModule', '''\ @@ -1525,8 +1525,8 @@ Args: model (str): 指定要访问的模型 (注意使用豆包时需用 Model ID 或 Endpoint ID,获取方式详见 [获取推理接入点](https://www.volcengine.com/docs/82379/1099522)。使用模型前,要先在豆包平台开通对应服务。),默认为 ``gpt-3.5-turbo(openai)`` / ``SenseChat-5(sensenova)`` / ``glm-4(glm)`` / ``moonshot-v1-8k(kimi)`` / ``qwen-plus(qwen)`` / ``mistral-7b-instruct-v0.2(doubao)`` / ``deepseek/deepseek-v3.2(ppio)`` - source (str): 指定要创建的模块类型,可选为 ``openai`` / ``sensenova`` / ``glm`` / ``kimi`` / ``qwen`` / ``doubao`` / ``ppio`` / ``deepseek(暂时不支持访问)`` - base_url (str): 指定要访问的平台的基础链接,默认是官方链接 + source (str): 指定要创建的模块类型,可选为 ``openai`` / ``sensenova`` / ``glm`` / ``kimi`` / ``qwen`` / ``doubao`` / ``ppio`` / ``deepseek(暂时不支持访问)``。也可以直接将 source 名称作为 ``model`` 传入,系统会自动识别并交换两者。 + url (str): 指定要访问的平台的基础链接,默认是官方链接。也可使用别名 ``base_url`` 传入。 system_prompt (str): 指定请求的system prompt,默认是官方给的system prompt api_key (str): 可显式传入 API Key;当设置为 ``auto`` 或 ``dynamic`` 时,将在运行时从配置读取,支持动态切换 key stream (bool): 是否流式请求和输出,默认为流式 @@ -1538,9 +1538,9 @@ Used to manage and create access modules for large model platforms currently available on the market. Currently, it supports openai, sensenova, glm, kimi, qwen, doubao, ppio and deepseek (since the platform does not allow recharges for the time being, access is not supported for the time being). For how to obtain the platform's API key, please visit [Getting Started](/#platform) Args: - model (str): Specify the model to access (Note that you need to use Model ID or Endpoint ID when using Doubao. For details on how to obtain it, see [Getting the Inference Access Point](https://www.volcengine.com/docs/82379/1099522). Before using the model, you must first activate the corresponding service on the Doubao platform.), default is ``gpt-3.5-turbo(openai)`` / ``SenseChat-5(sensenova)`` / ``glm-4(glm)`` / ``moonshot-v1-8k(kimi)`` / ``qwen-plus(qwen)`` / ``mistral-7b-instruct-v0.2(doubao)`` / ``deepseek/deepseek-v3.2(ppio)`` . + model (str): Specify the model to access (Note that you need to use Model ID or Endpoint ID when using Doubao. For details on how to obtain it, see [Getting the Inference Access Point](https://www.volcengine.com/docs/82379/1099522). Before using the model, you must first activate the corresponding service on the Doubao platform.), default is ``gpt-3.5-turbo(openai)`` / ``SenseChat-5(sensenova)`` / ``glm-4(glm)`` / ``moonshot-v1-8k(kimi)`` / ``qwen-plus(qwen)`` / ``mistral-7b-instruct-v0.2(doubao)`` / ``deepseek/deepseek-v3.2(ppio)`` . A recognised source name can also be passed here; it will be automatically swapped into ``source``. source (str): Specify the type of module to create. Options include ``openai`` / ``sensenova`` / ``glm`` / ``kimi`` / ``qwen`` / ``doubao`` / ``ppio`` / ``deepseek (not yet supported)`` . - base_url (str): Specify the base link of the platform to be accessed. The default is the official link. + url (str): Specify the base link of the platform to be accessed. The default is the official link. The alias ``base_url`` is also accepted. system_prompt (str): Specify the requested system prompt. The default is the official system prompt. api_key (str): You can pass an explicit API key. If set to ``auto`` or ``dynamic``, the key is resolved from config at runtime, enabling dynamic key switching. stream (bool): Whether to request and output in streaming mode, default is streaming. @@ -1677,22 +1677,28 @@ 用来管理创建目前市面上的在线Embedding服务模块,目前支持openai、sensenova、glm、qwen、doubao Args: + model (str): 指定要访问的模型 (注意使用豆包时需用 Model ID 或 Endpoint ID,获取方式详见 [获取推理接入点](https://www.volcengine.com/docs/82379/1099522)。使用模型前,要先在豆包平台开通对应服务。),默认为 ``text-embedding-ada-002(openai)`` / ``nova-embedding-stable(sensenova)`` / ``embedding-2(glm)`` / ``text-embedding-v1(qwen)`` / ``doubao-embedding-text-240715(doubao)``。也可使用别名 ``embed_model_name`` 或 ``model_name`` 传入。也可将 source 名称直接作为 ``model`` 传入,系统会自动识别并交换两者。 source (str): 指定要创建的模块类型,可选为 ``openai`` / ``sensenova`` / ``glm`` / ``qwen`` / ``doubao`` - embed_url (str): 指定要访问的平台的基础链接,默认是官方链接 - embed_mode_name (str): 指定要访问的模型 (注意使用豆包时需用 Model ID 或 Endpoint ID,获取方式详见 [获取推理接入点](https://www.volcengine.com/docs/82379/1099522)。使用模型前,要先在豆包平台开通对应服务。),默认为 ``text-embedding-ada-002(openai)`` / ``nova-embedding-stable(sensenova)`` / ``embedding-2(glm)`` / ``text-embedding-v1(qwen)`` / ``doubao-embedding-text-240715(doubao)`` + url (str): 指定要访问的平台的基础链接,默认是官方链接。也可使用别名 ``embed_url`` 或 ``base_url`` 传入。 + type (str): 模型服务类型,可选 ``embed`` / ``rerank``,默认根据模型名自动推断。 api_key (str): 可显式传入 API Key;当设置为 ``auto`` 或 ``dynamic`` 时,将在运行时从配置读取,支持动态切换 key dynamic_auth (bool): 是否启用动态鉴权;为 True 时等价于 ``api_key='dynamic'`` + return_trace (bool): 是否将结果记录在trace中,默认为False + batch_size (int): 批量请求时每批的大小,默认为32 ''') add_english_doc('OnlineEmbeddingModule', '''\ Used to manage and create online Embedding service modules currently on the market, currently supporting openai, sensenova, glm, qwen, doubao. Args: + model (str): Specify the model to access (Note that you need to use Model ID or Endpoint ID when using Doubao. For details on how to obtain it, see [Getting the Inference Access Point](https://www.volcengine.com/docs/82379/1099522). Before using the model, you must first activate the corresponding service on the Doubao platform.), default is ``text-embedding-ada-002(openai)`` / ``nova-embedding-stable(sensenova)`` / ``embedding-2(glm)`` / ``text-embedding-v1(qwen)`` / ``doubao-embedding-text-240715(doubao)``. The aliases ``embed_model_name`` and ``model_name`` are also accepted. A recognised source name can be passed here too; it will be automatically swapped into ``source``. source (str): Specify the type of module to create. Options are ``openai`` / ``sensenova`` / ``glm`` / ``qwen`` / ``doubao``. - embed_url (str): Specify the base link of the platform to be accessed. The default is the official link. - embed_mode_name (str): Specify the model to access (Note that you need to use Model ID or Endpoint ID when using Doubao. For details on how to obtain it, see [Getting the Inference Access Point](https://www.volcengine.com/docs/82379/1099522). Before using the model, you must first activate the corresponding service on the Doubao platform.), default is ``text-embedding-ada-002(openai)`` / ``nova-embedding-stable(sensenova)`` / ``embedding-2(glm)`` / ``text-embedding-v1(qwen)`` / ``doubao-embedding-text-240715(doubao)`` + url (str): Specify the base link of the platform to be accessed. The default is the official link. The aliases ``embed_url`` and ``base_url`` are also accepted. + type (str): Service type, either ``embed`` or ``rerank``. Inferred from the model name when omitted. api_key (str): You can pass an explicit API key. If set to ``auto`` or ``dynamic``, the key is resolved from config at runtime, enabling dynamic key switching. dynamic_auth (bool): Whether to enable dynamic auth. When True, it is equivalent to ``api_key='dynamic'``. + return_trace (bool): Whether to record the results in trace. Defaults to False. + batch_size (int): Batch size for bulk requests. Defaults to 32. ''') add_example('OnlineEmbeddingModule', '''\ @@ -1701,6 +1707,8 @@ >>> emb = m("hello world") >>> print(f"emb: {emb}") emb: [0.0010528564, 0.0063285828, 0.0049476624, -0.012008667, ..., -0.009124756, 0.0032043457, -0.051696777] +>>> m2 = lazyllm.OnlineEmbeddingModule("sensenova") +>>> emb2 = m2("hello world") ''') add_chinese_doc('OnlineMultiModalModule', '''\ @@ -1710,7 +1718,7 @@ model (str): 指定要访问的模型名称。 source (str): 指定要创建的模块类型,如 ``qwen`` / ``glm`` / ``minimax`` / ``siliconflow`` / ``doubao`` 等。 type (str): 多模态任务类型,可选 ``stt`` / ``tts`` / ``text2image`` / ``image_editing``。 - base_url (str): 指定要访问的平台基础链接,默认使用各平台官方链接。 + url (str): 指定要访问的平台基础链接,默认使用各平台官方链接。也可使用别名 ``base_url`` 传入。 api_key (str): 可显式传入 API Key;当设置为 ``auto`` 或 ``dynamic`` 时,将在运行时从配置读取,支持动态切换 key。 dynamic_auth (bool): 是否启用动态鉴权;为 True 时等价于 ``api_key='dynamic'``。 return_trace (bool): 是否将结果记录在 trace 中,默认为 False。 @@ -1723,7 +1731,7 @@ model (str): Model name to use. source (str): Supplier to use, such as ``qwen`` / ``glm`` / ``minimax`` / ``siliconflow`` / ``doubao``. type (str): Multimodal task type, one of ``stt`` / ``tts`` / ``text2image`` / ``image_editing``. - base_url (str): Base URL of the platform. Defaults to each supplier's official endpoint. + url (str): Base URL of the platform. Defaults to each supplier's official endpoint. The alias ``base_url`` is also accepted. api_key (str): You can pass an explicit API key. If set to ``auto`` or ``dynamic``, the key is resolved from config at runtime, enabling dynamic key switching. dynamic_auth (bool): Whether to enable dynamic auth. When True, it is equivalent to ``api_key='dynamic'``. return_trace (bool): Whether to record the result in trace. Defaults to False.