Merge remote-tracking branch 'origin' into feat/vl_pipeline

This commit is contained in:
suluyana
2024-11-04 13:58:57 +08:00
21 changed files with 1040 additions and 155 deletions

View File

@@ -138,4 +138,5 @@ RUN set -eux; \
pip --version
# end of install python
RUN pip install tf-keras -i https://mirrors.aliyun.com/pypi/simple
RUN pip install tensorflow-cpu==2.16.1
RUN pip install tf-keras==2.16.0 --no-dependencies

View File

@@ -46,6 +46,8 @@ RUN cd /tmp && GIT_LFS_SKIP_SMUDGE=1 git clone -b {swift_branch} --single-branc
RUN pip install --no-cache-dir torch=={torch_version} torchvision=={torchvision_version} torchaudio=={torchaudio_version} {index_url}
RUN pip install --no-cache-dir transformers -U huggingface-hub==0.25.0
RUN pip config set global.index-url https://mirrors.aliyun.com/pypi/simple && \
pip config set install.trusted-host mirrors.aliyun.com && \
cp /tmp/resources/ubuntu2204.aliyun /etc/apt/sources.list
@@ -54,3 +56,4 @@ ENV SETUPTOOLS_USE_DISTUTILS=stdlib
ENV VLLM_USE_MODELSCOPE=True
ENV LMDEPLOY_USE_MODELSCOPE=True
ENV MODELSCOPE_CACHE=/mnt/workspace/.cache/modelscope
SHELL ["/bin/bash", "-c"]

View File

@@ -22,6 +22,8 @@ import requests
from requests import Session
from requests.adapters import HTTPAdapter, Retry
from modelscope import utils
from modelscope.fileio import io
from modelscope.hub.constants import (API_HTTP_CLIENT_MAX_RETRIES,
API_HTTP_CLIENT_TIMEOUT,
API_RESPONSE_FIELD_DATA,
@@ -48,13 +50,14 @@ from modelscope.utils.constant import (DEFAULT_DATASET_REVISION,
DEFAULT_MODEL_REVISION,
DEFAULT_REPOSITORY_REVISION,
MASTER_MODEL_BRANCH, META_FILES_FORMAT,
REPO_TYPE_MODEL, ConfigFields,
DatasetFormations, DatasetMetaFormats,
DatasetVisibilityMap, DownloadChannel,
DownloadMode, ModelFile,
VirgoDatasetConfig)
DownloadMode, Frameworks, ModelFile,
Tasks, VirgoDatasetConfig)
from modelscope.utils.logger import get_logger
from .utils.utils import (get_endpoint, get_release_datetime,
model_id_to_group_owner_name)
from .utils.utils import (get_endpoint, get_readable_folder_size,
get_release_datetime, model_id_to_group_owner_name)
logger = get_logger()
@@ -248,6 +251,57 @@ class HubApi:
else:
raise_for_http_status(r)
def repo_exists(
self,
repo_id: str,
*,
repo_type: Optional[str] = None,
) -> bool:
"""
Checks if a repository exists on ModelScope
Args:
repo_id (`str`):
A namespace (user or an organization) and a repo name separated
by a `/`.
repo_type (`str`, *optional*):
`None` or `"model"` if getting repository info from a model. Default is `None`.
TODO: support dataset and studio
Returns:
True if the repository exists, False otherwise.
"""
if (repo_type is not None) and repo_type.lower != REPO_TYPE_MODEL:
raise Exception('Not support repo-type: %s' % repo_type)
if (repo_id is None) or repo_id.count('/') != 1:
raise Exception('Invalid repo_id: %s, must be of format namespace/name' % repo_type)
cookies = ModelScopeConfig.get_cookies()
owner_or_group, name = model_id_to_group_owner_name(repo_id)
path = f'{self.endpoint}/api/v1/models/{owner_or_group}/{name}'
r = self.session.get(path, cookies=cookies,
headers=self.builder_headers(self.headers))
code = handle_http_response(r, logger, cookies, repo_id, False)
if code == 200:
return True
elif code == 404:
return False
else:
logger.warn(f'Check repo_exists return status code {code}.')
raise Exception(
'Failed to check existence of repo: %s, make sure you have access authorization.'
% repo_type)
@staticmethod
def _create_default_config(model_dir):
cfg_file = os.path.join(model_dir, ModelFile.CONFIGURATION)
cfg = {
ConfigFields.framework: Frameworks.torch,
ConfigFields.task: Tasks.other,
}
io.dump(cfg, cfg_file)
def push_model(self,
model_id: str,
model_dir: str,
@@ -315,23 +369,23 @@ class HubApi:
raise InvalidParameter('model_dir must be a valid directory.')
cfg_file = os.path.join(model_dir, ModelFile.CONFIGURATION)
if not os.path.exists(cfg_file):
raise ValueError(f'{model_dir} must contain a configuration.json.')
logger.warning(
f'No {ModelFile.CONFIGURATION} file found in {model_dir}, creating a default one.')
HubApi._create_default_config(model_dir)
cookies = ModelScopeConfig.get_cookies()
if cookies is None:
raise NotLoginException('Must login before upload!')
files_to_save = os.listdir(model_dir)
folder_size = get_readable_folder_size(model_dir)
if ignore_file_pattern is None:
ignore_file_pattern = []
if isinstance(ignore_file_pattern, str):
ignore_file_pattern = [ignore_file_pattern]
try:
self.get_model(model_id=model_id)
except Exception:
if visibility is None or license is None:
raise InvalidParameter(
'visibility and license cannot be empty if want to create new repo'
)
logger.info('Create new model %s' % model_id)
if visibility is None or license is None:
raise InvalidParameter('Visibility and License cannot be empty for new model.')
if not self.repo_exists(model_id):
logger.info('Creating new model [%s]' % model_id)
self.create_model(
model_id=model_id,
visibility=visibility,
@@ -340,11 +394,13 @@ class HubApi:
original_model_id=original_model_id)
tmp_dir = tempfile.mkdtemp()
git_wrapper = GitCommandWrapper()
logger.info(f'Pushing folder {model_dir} as model {model_id}.')
logger.info(f'Total folder size {folder_size}, this may take a while depending on actual pushing size...')
try:
repo = Repository(model_dir=tmp_dir, clone_from=model_id)
branches = git_wrapper.get_remote_branches(tmp_dir)
if revision not in branches:
logger.info('Create new branch %s' % revision)
logger.info('Creating new branch %s' % revision)
git_wrapper.new_branch(tmp_dir, revision)
git_wrapper.checkout(tmp_dir, revision)
files_in_repo = os.listdir(tmp_dir)

View File

@@ -2,6 +2,7 @@
import logging
from http import HTTPStatus
from typing import Optional
import requests
from requests.exceptions import HTTPError
@@ -86,8 +87,11 @@ def handle_http_post_error(response, url, request_body):
(url, request_body, message, get_request_id(response))) from error
def handle_http_response(response: requests.Response, logger, cookies,
model_id):
def handle_http_response(response: requests.Response,
logger,
cookies,
model_id,
raise_on_error: Optional[bool] = True) -> int:
http_error_msg = ''
if isinstance(response.reason, bytes):
try:
@@ -113,9 +117,11 @@ def handle_http_response(response: requests.Response, logger, cookies,
elif 500 <= response.status_code < 600:
http_error_msg = u'%s Server Error: %s, Request id: %s, for url: %s' % (
response.status_code, reason, request_id, response.url)
if http_error_msg: # there is error.
if http_error_msg and raise_on_error: # there is error.
logger.error(http_error_msg)
raise HTTPError(http_error_msg, response=response)
else:
return response.status_code
def raise_on_error(rsp):

View File

@@ -56,11 +56,18 @@ class GitCommandWrapper(metaclass=Singleton):
response.check_returncode()
return response
except subprocess.CalledProcessError as error:
output = 'stdout: %s, stderr: %s' % (
response.stdout.decode('utf8'), error.stderr.decode('utf8'))
logger.error('Running git command: %s failed, output: %s.' %
(command, output))
raise GitError(output)
std_out = response.stdout.decode('utf8')
std_err = error.stderr.decode('utf8')
if 'nothing to commit' in std_out:
logger.info(
'Nothing to commit, your local repo is upto date with remote'
)
return response
else:
logger.error(
'Running git command: %s failed \n stdout: %s \n stderr: %s'
% (command, std_out, std_err))
raise GitError(std_err)
def config_auth_token(self, repo_dir, auth_token):
url = self.get_repo_remote_url(repo_dir)

View File

@@ -193,7 +193,9 @@ def _snapshot_download(
temporary_cache_dir, cache = create_temporary_directory_and_cache(
repo_id, local_dir=local_dir, cache_dir=cache_dir, repo_type=repo_type)
system_cache = cache_dir if cache_dir is not None else os.getenv(
'MODELSCOPE_CACHE',
Path.home().joinpath('.cache', 'modelscope'))
if local_files_only:
if len(cache.cached_files) == 0:
raise ValueError(
@@ -217,6 +219,8 @@ def _snapshot_download(
if cookies is None:
cookies = ModelScopeConfig.get_cookies()
repo_files = []
directory = os.path.join(system_cache, 'hub', repo_id)
print(f'Downloading Model to directory: {directory}')
if repo_type == REPO_TYPE_MODEL:
revision_detail = _api.get_valid_revision_detail(
repo_id, revision=revision, cookies=cookies)
@@ -257,6 +261,8 @@ def _snapshot_download(
allow_patterns=allow_patterns)
elif repo_type == REPO_TYPE_DATASET:
directory = os.path.join(system_cache, 'datasets', repo_id)
print(f'Downloading Dataset to directory: {directory}')
group_or_owner, name = model_id_to_group_owner_name(repo_id)
if not revision:
revision = DEFAULT_DATASET_REVISION

View File

@@ -29,6 +29,30 @@ def model_id_to_group_owner_name(model_id):
return group_or_owner, name
def convert_readable_size(size_bytes):
import math
if size_bytes == 0:
return '0B'
size_name = ('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')
i = int(math.floor(math.log(size_bytes, 1024)))
p = math.pow(1024, i)
s = round(size_bytes / p, 2)
return f'{s} {size_name[i]}'
def get_folder_size(folder_path):
total_size = 0
for path in Path(folder_path).rglob('*'):
if path.is_file():
total_size += path.stat().st_size
return total_size
# return a readable string that describe size of for a given folder (MB, GB etc.)
def get_readable_folder_size(folder_path) -> str:
return convert_readable_size(get_folder_size(folder_path=folder_path))
def get_cache_dir(model_id: Optional[str] = None):
"""cache dir precedence:
function parameter > environment > ~/.cache/modelscope/hub

View File

@@ -82,5 +82,5 @@ class BartForTextErrorCorrection(TorchModel):
batch_preds = []
for i in range(batch_size):
# get 1-best List[Tensor]
batch_preds.append(translations[i][0]['tokens'])
batch_preds.append(translations[i][0]['tokens'].tolist())
return TextErrorCorrectionOutput(predictions=batch_preds)

View File

@@ -326,7 +326,7 @@ class TextErrorCorrectionOutput(ModelOutputBase):
"""The output class for information extraction models.
"""
predictions: np.ndarray = None
predictions: List = None
@dataclass

View File

@@ -151,9 +151,8 @@ class ANSZipEnhancerPipeline(Pipeline):
if isinstance(inputs, bytes):
data1, fs = sf.read(io.BytesIO(inputs))
elif isinstance(inputs, str):
# file_bytes = File.read(inputs)
# data1, fs = sf.read(io.BytesIO(file_bytes))
data1, fs = sf.read(inputs)
file_bytes = File.read(inputs)
data1, fs = sf.read(io.BytesIO(file_bytes))
else:
raise TypeError(f'Unsupported type {type(inputs)}.')
if len(data1.shape) > 1:

View File

@@ -481,7 +481,10 @@ class DistributedPipeline(Pipeline):
def __del__(self):
if hasattr(self, 'model_pool') and self.model_pool is not None:
self.model_pool.terminate()
try:
self.model_pool.terminate()
except AttributeError:
pass
def __getstate__(self):
self_dict = self.__dict__.copy()

View File

@@ -6,7 +6,6 @@ from typing import Any, Dict
import cv2
import numpy as np
import tensorflow as tf
import torch
from modelscope.metainfo import Pipelines
@@ -19,18 +18,7 @@ from modelscope.utils.config import Config
from modelscope.utils.constant import ModelFile, Tasks
from modelscope.utils.device import device_placement
from modelscope.utils.logger import get_logger
from .ocr_utils import (SegLinkDetector, boxes_from_bitmap, cal_width,
combine_segments_python, decode_segments_links_python,
nms_python, polygons_from_bitmap, rboxes_to_polygons)
if tf.__version__ >= '2.0':
import tf_slim as slim
else:
from tensorflow.contrib import slim
if tf.__version__ >= '2.0':
tf = tf.compat.v1
tf.compat.v1.disable_eager_execution()
from .ocr_utils import cal_width, nms_python, rboxes_to_polygons
logger = get_logger()
@@ -40,12 +28,6 @@ OFFSET_DIM = 6
WORD_POLYGON_DIM = 8
OFFSET_VARIANCE = [0.1, 0.1, 0.1, 0.1, 0.1, 0.1]
FLAGS = tf.app.flags.FLAGS
tf.app.flags.DEFINE_float('node_threshold', 0.4,
'Confidence threshold for nodes')
tf.app.flags.DEFINE_float('link_threshold', 0.6,
'Confidence threshold for links')
@PIPELINES.register_module(
Tasks.ocr_detection, module_name=Pipelines.ocr_detection)
@@ -99,6 +81,16 @@ class OCRDetectionPipeline(Pipeline):
logger.info('loading model done')
else:
# for model seglink++
import tensorflow as tf
if tf.__version__ >= '2.0':
tf = tf.compat.v1
tf.compat.v1.disable_eager_execution()
tf.app.flags.DEFINE_float('node_threshold', 0.4,
'Confidence threshold for nodes')
tf.app.flags.DEFINE_float('link_threshold', 0.6,
'Confidence threshold for links')
tf.reset_default_graph()
model_path = osp.join(
osp.join(self.model, ModelFile.TF_CHECKPOINT_FOLDER),
@@ -125,6 +117,7 @@ class OCRDetectionPipeline(Pipeline):
variable_averages = tf.train.ExponentialMovingAverage(
0.997, global_step)
from .ocr_utils import SegLinkDetector, combine_segments_python, decode_segments_links_python
# detector
detector = SegLinkDetector()
all_maps = detector.build_model(
@@ -198,6 +191,19 @@ class OCRDetectionPipeline(Pipeline):
result = self.preprocessor(input)
return result
else:
# for model seglink++
import tensorflow as tf
if tf.__version__ >= '2.0':
tf = tf.compat.v1
tf.compat.v1.disable_eager_execution()
tf.app.flags.DEFINE_float('node_threshold', 0.4,
'Confidence threshold for nodes')
tf.app.flags.DEFINE_float('link_threshold', 0.6,
'Confidence threshold for links')
img = LoadImage.convert_to_ndarray(input)
h, w, c = img.shape

View File

@@ -80,7 +80,8 @@ class TextErrorCorrectionPipeline(Pipeline):
sc_tensor = inputs['predictions']
if isinstance(sc_tensor, list):
sc_tensor = sc_tensor[0]
if isinstance(sc_tensor[0], list):
sc_tensor = sc_tensor[0]
sc_sent = self.vocab.string(
sc_tensor, extra_symbols_to_ignore={self.vocab.pad()})
sc_sent = (sc_sent + ' ').replace('##', '').rstrip()

View File

@@ -1,6 +1,7 @@
import re
import json
from dataclasses import dataclass
from typing import Any, Dict, List
from typing import Any, Dict, List, Union, Optional, Tuple
import requests
@@ -16,7 +17,7 @@ class TemplateInfo:
template: str = None
template_regex: str = None
modelfile_link: str = None
modelfile_prefix: str = None
def cases(*names):
@@ -48,52 +49,374 @@ def no_multi_modal():
return no('audio', 'video', 'vl', 'vision')
# Order matters
template_info = [
# llama
## "llama3"
TemplateInfo(
template=TemplateType.llama3,
template_regex=
f'.*{cases("llama3.2", "llama-3.2")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llama3.2',
),
TemplateInfo(
template=TemplateType.llama3,
template_regex=
f'.*{cases("llama3.1", "llama-3.1")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llama3.1',
),
TemplateInfo(
template_regex=
f'.*{cases("llama3", "llama-3")}.*{no_multi_modal()}.*{chat_suffix}.*{cases("gradient")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llama3-gradient',
),
TemplateInfo(
template_regex=
f'.*{cases("llama3", "llama-3")}.*{no_multi_modal()}.*{cases("groq")}.*{cases("tool-use", "tool_use")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llama3-groq-tool-use',
),
TemplateInfo(
template_regex=
f'.*{cases("llama3", "llama-3")}.*{no_multi_modal()}.*{cases("chatqa")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llama3-chatqa',
),
TemplateInfo(
template_regex=f'.*{cases("llava-llama-3")}.*',
modelfile_prefix='https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llava-llama3'),
TemplateInfo(
template_regex=f'.*{cases("dolphin")}.*{cases("llama3")}.*',
modelfile_prefix='https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/dolphin-llama3'),
TemplateInfo(
template=TemplateType.llama3,
template_regex=
f'.*{cases("llama3", "llama-3")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_link=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llama-3.modelfile',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llama3',
),
## "llama"
TemplateInfo(
template_regex=
f'.*{cases("llama2", "llama-2")}{no_multi_modal()}.*{cases("chinese")}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llama2-chinese',
),
TemplateInfo(
template_regex=
f'.*{cases("codellama")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/codellama',
),
TemplateInfo(
template_regex=
f'.*{cases("tinyllama")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/tinyllama',
),
TemplateInfo(
template_regex=
f'.*{cases("llama-pro", "llama_pro")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llama-pro',
),
TemplateInfo(
template_regex=
f'.*{cases("llama")}.*{cases("guard")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llama-guard3',
),
TemplateInfo(
template=TemplateType.llama,
template_regex=
f'.*{cases("llama2", "llama-2", "mistral", "codestral", "mixtral")}{no_multi_modal()}.*{chat_suffix}.*'
f'.*{cases("llama")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llama2',
),
# qwen
TemplateInfo(
template=TemplateType.qwen,
template_regex=f'.*{cases("qwen")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_link=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/qwen2.modelfile',
template_regex=f'.*{cases("qwen2.5")}.*{cases("coder")}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/qwen2.5-coder',
),
TemplateInfo(
template=TemplateType.qwen,
template_regex=f'.*{cases("qwen2.5")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/qwen2.5',
),
TemplateInfo(
template_regex=f'.*{cases("qwen2-math")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/qwen2-math',
),
# codeqwen1.5
TemplateInfo(
template_regex=
f'.*{cases("codeqwen1.5", "codeqwen-1.5")}.*{chat_suffix}.*',
modelfile_link=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/codeqwen1.5.modelfile',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/codeqwen',
),
TemplateInfo(
template=TemplateType.qwen,
template_regex=f'.*{cases("qwen2", "qwen1.5")}{no_multi_modal()}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/qwen2',
),
TemplateInfo(
template=TemplateType.qwen,
template_regex=f'.*{cases("qwen")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/qwen',
),
# chatml
# gemma
TemplateInfo(
template_regex=
f'.*{cases("codegemma")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/codegemma',
),
TemplateInfo(
template=TemplateType.gemma,
template_regex=
f'{no("pali")}.*{cases("gemma2", "gemma-2")}\\b.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/gemma2',
),
TemplateInfo(
template_regex=
f'.*{cases("shieldgemma")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/shieldgemma',
),
TemplateInfo(
template=TemplateType.gemma,
template_regex=
f'{no("pali")}.*{cases("gemma")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/gemma',
),
# "dolphin"
TemplateInfo(
template_regex=
f'.*{cases("dolphin")}.*{cases("-mixtral")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/dolphin-mixtral',
),
TemplateInfo(
template_regex=
f'.*{cases("dolphin")}.*{cases("mistral")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/dolphin-mistral',
),
# "phi"
TemplateInfo(
template_regex=
f'.*{cases("llava-phi3", "llava-phi-3")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llava-phi3',
),
TemplateInfo(
template_regex=
f'.*{cases("phi3.5", "phi-3.5")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/phi3.5',
),
TemplateInfo(
template=TemplateType.phi3,
template_regex=
f'.*{cases("phi3", "phi-3")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/phi3',
),
TemplateInfo(
template_regex=
f'.*{cases("phi")}{no_multi_modal()}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/phi',
),
# "mistral"
TemplateInfo(
template_regex=
f'.*{cases("yarn")}.*{cases("mistral")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/yarn-mistral',
),
TemplateInfo(
template_regex=
f'.*{cases("mistral")}.*{cases("large")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/mistral-large',
),
TemplateInfo(
template_regex=
f'.*{cases("mistral")}.*{cases("small")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/mistral-small',
),
TemplateInfo(
template=TemplateType.mistral_nemo,
template_regex=f'.*{cases("Mistral-Nemo")}{no_multi_modal()}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/mistral-nemo',
),
TemplateInfo(
template_regex=
f'.*{cases("mistral")}.*{cases("openorca")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/mistral-openorca',
),
TemplateInfo(
template_regex=
f'.*{cases("mistrallite")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/mistrallite',
),
## other mistral: set Type.llama
TemplateInfo(
template=TemplateType.llama,
template_regex=
f'.*{cases("mistral")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/mistral',
),
# "mixtral"
TemplateInfo(
template_regex=
f'.*{cases("nous-hermes2", "nous-hermes-2")}.*{cases("mixtral")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/nous-hermes2-mixtral',
),
TemplateInfo(
template=TemplateType.llama,
template_regex=
f'.*{cases("mixtral")}{no_multi_modal()}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/mixtral',
),
# codestral
TemplateInfo(
template=TemplateType.llama,
template_regex=
f'.*{cases("codestral")}{no_multi_modal()}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/codestral',
),
# nous-hermes2
TemplateInfo(
template_regex=
f'.*{cases("nous-hermes2", "nous-hermes-2")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/nous-hermes2',
),
TemplateInfo(
template_regex=f'.*{cases("nous-hermes")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/nous-hermes'),
# "deepseek"
TemplateInfo(
template=TemplateType.deepseek2_5,
template_regex=
f'.*{cases("deepseek")}.*{cases("v2.5")}{no_multi_modal()}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/deepseek-v2.5',
),
TemplateInfo(
template=TemplateType.deepseek_coder,
template_regex=
f'.*{cases("deepseek")}.*{cases("coder")}.*{cases("v2")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/deepseek-coder-v2',
),
TemplateInfo(
template=TemplateType.deepseek_coder,
template_regex=
f'.*{cases("deepseek")}{no("v2", "v2.5")}.*{cases("coder")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/deepseek-coder',
),
TemplateInfo(
template=TemplateType.deepseek2,
template_regex=
f'.*{cases("deepseek")}.*{cases("v2")}{no("v2.5")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/deepseek-v2',
),
TemplateInfo(
template=TemplateType.deepseek,
template_regex=
f'.*{cases("deepseek")}{no("v2", "v2.5", "coder")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/deepseek-llm',
),
# "yi"
TemplateInfo(
template=TemplateType.yi_coder,
template_regex=f'.*{cases("yi")}.*{cases("coder")}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/yi-coder',
),
TemplateInfo(
template=TemplateType.chatml,
template_regex=
f'.*{cases("yi")}{no_multi_modal()}{no("coder")}.*',
modelfile_link=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/yi-1.5.modelfile',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/yi',
),
# chatml
# "llava"
TemplateInfo(
template_regex=
f'.*{cases("bakllava")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/bakllava',
),
TemplateInfo(
template_regex=
f'.*{cases("llava")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llava',
),
# "nemotron"
TemplateInfo(
template_regex=
f'.*{cases("nemotron-mini")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/nemotron-mini',
),
TemplateInfo(
template_regex=
f'.*{cases("nemotron")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/nemotron',
),
# "minicpm"
TemplateInfo(
template_regex=f'.*{cases("minicpm-v")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/minicpm-v'
),
TemplateInfo(
template=TemplateType.chatml,
template_regex=f'.*{cases("minicpm")}{no("-v")}.*',
modelfile_link=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/yi-1.5.modelfile'
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/yi'
),
# chatglm
@@ -105,37 +428,98 @@ template_info = [
template_regex=f'.*{cases("chatglm3")}{no_multi_modal()}.*'),
TemplateInfo(
template=TemplateType.chatglm4,
template_regex=f'.*{cases("glm4")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_link=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/glm4.modelfile',
template_regex=f'.*{cases("glm4", "glm-4")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/glm4',
),
TemplateInfo(
template_regex=f'.*{cases("llava-llama-3")}.*',
modelfile_link='https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/llava-llama-3.modelfile'),
# baichuan
TemplateInfo(
template=TemplateType.baichuan,
template_regex=
f'.*{cases("baichuan")}{no_multi_modal()}.*{chat_suffix}.*'),
# "command-r"
TemplateInfo(
template_regex=
f'.*{cases("command-r-plus")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/command-r-plus',
),
TemplateInfo(
template_regex=
f'.*{cases("command-r")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/command-r',
),
# codegeex
TemplateInfo(
template=TemplateType.codegeex4,
template_regex=f'.*{cases("codegeex4")}{no_multi_modal()}.*'),
template_regex=f'.*{cases("codegeex4")}{no_multi_modal()}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/codegeex4',
),
# wizard
TemplateInfo(
template_regex=
f'.*{cases("wizard-vicuna")}.*{cases("uncensored")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/wizard-vicuna-uncensored',
),
TemplateInfo(
template_regex=
f'.*{cases("wizardlm2", "wizardlm-2")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/wizardlm2',
),
TemplateInfo(
template_regex=
f'.*{cases("wizardcoder")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/wizardcoder',
),
TemplateInfo(
template_regex=
f'.*{cases("wizard-math", "wizardmath")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/wizard-math',
),
TemplateInfo(
template_regex=
f'.*{cases("wizardlm")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/wizardlm',
),
# vicuna
TemplateInfo(
template_regex=
f'.*{cases("vicuna")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/vicuna',
),
# "stable"
TemplateInfo(
template_regex=
f'.*{cases("stable-code")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/stable-code',
),
TemplateInfo(
template_regex=
f'.*{cases("stablelm")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/stablelm2',
),
# idefics3
TemplateInfo(
template=TemplateType.idefics3,
template_regex=f'.*{cases("idefics3")}{no_multi_modal()}.*'),
# mistral-nemo
TemplateInfo(
template=TemplateType.mistral_nemo,
template_regex=f'.*{cases("Mistral-Nemo")}{no_multi_modal()}.*',
modelfile_link='https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/mistral-nemo.modelfile'),
# internlm
TemplateInfo(
template=TemplateType.internlm,
@@ -147,12 +531,10 @@ template_info = [
TemplateInfo(
template=TemplateType.internlm2,
template_regex=
f'.*{cases("internlm2")}{no_multi_modal()}.*{chat_suffix}.*'),
# yi-coder
TemplateInfo(
template=TemplateType.yi_coder,
template_regex=f'.*{cases("yi")}.*{cases("coder")}.*{chat_suffix}.*'),
f'.*{cases("internlm2")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/internlm2',
),
# yuan
TemplateInfo(
@@ -194,8 +576,8 @@ template_info = [
template=TemplateType.deepseek2,
template_regex=
f'.*{cases("deepseek")}.*{cases("v2")}{no("v2.5")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_link=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/deepseek_v2.modelfile',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/deepseek_v2',
),
# deepseek_coder
@@ -217,24 +599,6 @@ template_info = [
template_regex=f'.*{cases("orion")}{no_multi_modal()}.*{chat_suffix}.*'
),
# gemma
TemplateInfo(
template=TemplateType.gemma,
template_regex=
f'{no("pali")}.*{cases("gemma2", "gemma-2")}\\b.*{chat_suffix}.*',
modelfile_link=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/gemma2.modelfile',
),
# phi3
TemplateInfo(
template=TemplateType.phi3,
template_regex=
f'.*{cases("phi3", "phi-3")}{no_multi_modal()}.*{chat_suffix}.*',
modelfile_link=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/phi3.modelfile',
),
# telechat
TemplateInfo(
template=TemplateType.telechat,
@@ -244,6 +608,164 @@ template_info = [
TemplateInfo(
template=TemplateType.telechat_v2,
template_regex=f'.*{cases("TeleChat")}.*{cases("v2")}.*'),
TemplateInfo(
template_regex=f'.*{cases("nomic-embed-text")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/nomic-embed-text'),
TemplateInfo(
template_regex=f'.*{cases("mxbai-embed-large")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/mxbai-embed-large'),
TemplateInfo(
template_regex=f'.*{cases("starcoder2")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/starcoder2'),
TemplateInfo(
template_regex=f'.*{cases("orca-mini", "orca_mini")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/orca-mini'),
TemplateInfo(
template_regex=f'.*{cases("zephyr")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/zephyr'),
TemplateInfo(
template_regex=f'.*{cases("snowflake-arctic-embed")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/snowflake-arctic-embed'),
TemplateInfo(
template_regex=f'.*{cases("starcoder")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/starcoder'),
TemplateInfo(
template_regex=f'.*{cases("granite")}.*{cases("code")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/granite-code'),
TemplateInfo(
template_regex=f'.*{cases("all-minilm")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/all-minilm'),
TemplateInfo(
template_regex=f'.*{cases("openchat")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/openchat'),
TemplateInfo(
template_regex=f'.*{cases("aya")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/aya'),
TemplateInfo(
template_regex=f'.*{cases("openhermes")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/openhermes'),
TemplateInfo(
template_regex=f'.*{cases("reflection")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/reflection'),
TemplateInfo(
template_regex=f'.*{cases("neural-chat")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/neural-chat'),
TemplateInfo(
template_regex=f'.*{cases("moondream")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/moondream'),
TemplateInfo(
template_regex=f'.*{cases("xwin")}.*{cases("lm")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/xwinlm'),
TemplateInfo(
template_regex=f'.*{cases("smollm")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/smollm'),
TemplateInfo(
template_regex=f'.*{cases("sqlcoder")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/sqlcoder'),
TemplateInfo(
template_regex=f'.*{cases("starling-lm")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/starling-lm'),
TemplateInfo(
template_regex=f'.*{cases("falcon")}.*{cases("-2")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/falcon2'),
TemplateInfo(
template_regex=f'.*{cases("falcon")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/falcon'),
TemplateInfo(
template_regex=f'.*{cases("solar-pro")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/solar-pro'),
TemplateInfo(
template_regex=f'.*{cases("solar")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/solar'),
TemplateInfo(
template_regex=f'.*{cases("orca2", "orca-2", "orca_2")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/orca2'),
TemplateInfo(
template_regex=f'.*{cases("hermes3", "hermes-3", "hermes_3")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/hermes3'),
TemplateInfo(
template_regex=f'.*{cases("meditron")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/meditron'),
TemplateInfo(
template_regex=f'.*{cases("nexusraven")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/nexusraven'),
TemplateInfo(
template_regex=f'.*{cases("magicoder")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/magicoder'),
TemplateInfo(
template_regex=f'.*{cases("bge-m3")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/bge-m3'),
TemplateInfo(
template_regex=f'.*{cases("notux")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/notux'),
TemplateInfo(
template_regex=f'.*{cases("open")}.*{cases("orca")}.*{cases("platypus2")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/open-orca-platypus2'),
TemplateInfo(
template_regex=f'.*{cases("notus")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/notus'),
TemplateInfo(
template_regex=f'.*{cases("mathstral")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/mathstral'),
TemplateInfo(
template_regex=f'.*{cases("dbrx")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/dbrx'),
TemplateInfo(
template_regex=f'.*{cases("nuextract")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/nuextract'),
TemplateInfo(
template_regex=f'.*{cases("reader-lm")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/reader-lm'),
TemplateInfo(
template_regex=f'.*{cases("alfred")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/alfred'),
TemplateInfo(
template_regex=f'.*{cases("bge-large")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/bge-large'),
TemplateInfo(
template_regex=f'.*{cases("paraphrase-multilingual")}.*',
modelfile_prefix=
'https://modelscope.oss-cn-beijing.aliyuncs.com/llm_template/ollama/paraphrase-multilingual'),
]
@@ -318,12 +840,35 @@ class TemplateLoader:
raise ValueError(f'Unknown token: {attr}')
return final_str
@staticmethod
def _format_return(template_lines: str, params: Dict, split: bool, license: Optional[str] = None) -> Union[str, Dict]:
if split:
if params:
params = json.dumps(params)
return {'params': params, 'template': template_lines, 'license': license}
content = ''
content += 'FROM {gguf_file}\n\n'
if params:
for key, values in params.items():
if isinstance(values, list):
for value in values:
content += f'PARAMETER {key} {json.dumps(value)}\n'
else:
content += f'PARAMETER {key} {json.dumps(values)}\n'
content += '\n'
if template_lines:
content += ('TEMPLATE """' + template_lines + '"""\n')
return content
@staticmethod
def to_ollama(model_id: str = None,
template_name: str = None,
gguf_file: str = None,
gguf_meta: Dict[str, Any] = None,
**kwargs) -> str:
split: bool = False,
debug: bool = False,
**kwargs) -> Union[str, Dict, Tuple[Dict, TemplateInfo], Tuple[str, TemplateInfo], None]:
"""Export to ollama ModelFile
Args:
@@ -331,20 +876,44 @@ class TemplateLoader:
template_name: An extra template name to use
gguf_file: An extra gguf_file path to use in the `FROM` field
gguf_meta: An gguf extra meta info
split: bool. Return str modelfile content, or dict of params and template
debug: bool. Whether or not to return the matched TemplateInfo
Returns:
The ModelFile content, returns `None` if no template found
The ModelFile content, or dictionary of params and template, returns `None` if no template found
"""
if not model_id and not template_name:
if not model_id and not template_name and not gguf_meta:
raise ValueError(
f'Please make sure you model_id: {model_id} '
f'and template_name: {template_name} is supported.')
logger.info('Exporting to ollama:')
names = []
if gguf_meta:
gguf_header_name = gguf_meta.get("general.name", None)
names.append(gguf_header_name)
if model_id:
names.append(model_id)
for name in names:
for _info in template_info:
if re.fullmatch(_info.template_regex, model_id):
if _info.modelfile_link and not kwargs.get('ignore_oss_model_file', False):
return TemplateLoader._read_content_from_url(
_info.modelfile_link)
if re.fullmatch(_info.template_regex, name):
if _info.modelfile_prefix and not kwargs.get('ignore_oss_model_file', False):
template_str = TemplateLoader._read_content_from_url(
_info.modelfile_prefix + '.template')
if not template_str:
logger.info(f'{name} has no template file.')
params = TemplateLoader._read_content_from_url(_info.modelfile_prefix + '.params')
if params:
params = json.loads(params)
else:
logger.info(f'{name} has no params file.')
license = TemplateLoader._read_content_from_url(
_info.modelfile_prefix + '.license')
if not template_str:
logger.info(f'{name} has no license file.')
format_out = TemplateLoader._format_return(template_str, params, split, license)
if debug:
return format_out, _info
return format_out
if template_name:
template = TemplateLoader.load_by_template_name(
template_name, **kwargs)
@@ -352,30 +921,31 @@ class TemplateLoader:
template = TemplateLoader.load_by_model_id(
model_id, **kwargs)
if template is None:
if not template:
return None
content = ''
content += 'FROM {gguf_file}\n'
# template
template_lines = ''
_prefix = TemplateLoader.replace_and_concat(template, template.prefix, "", "")
if _prefix:
content += (
f'TEMPLATE """{{{{ if .System }}}}'
template_lines += (
f'{{{{ if .System }}}}'
f'{TemplateLoader.replace_and_concat(template, template.system_prefix or [], "{{SYSTEM}}", "{{ .System }}")}'
f'{{{{ else }}}}{_prefix}'
f'{{{{ end }}}}')
else:
content += (
f'TEMPLATE """{{{{ if .System }}}}'
template_lines += (
f'{{{{ if .System }}}}'
f'{TemplateLoader.replace_and_concat(template, template.system_prefix or [], "{{SYSTEM}}", "{{ .System }}")}'
f'{{{{ end }}}}')
content += (
template_lines += (
f'{{{{ if .Prompt }}}}'
f'{TemplateLoader.replace_and_concat(template, template.prompt, "{{QUERY}}", "{{ .Prompt }}")}'
f'{{{{ end }}}}')
content += '{{ .Response }}'
content += TemplateLoader.replace_and_concat(template, template.suffix,
'', '') + '"""\n'
template_lines += '{{ .Response }}'
template_lines += TemplateLoader.replace_and_concat(template, template.suffix,
'', '')
# stop tokens
all_eos_tokens = {TemplateLoader.replace_and_concat(template, template.suffix, "", "")}
if getattr(template, 'tokenizer', None):
eos_token = TemplateLoader.replace_and_concat(template, [["eos_token_id"]], "", "")
@@ -384,13 +954,20 @@ class TemplateLoader:
eos_token_id = template.config.eos_token_id
eos_token = TemplateLoader.replace_and_concat(template, [[eos_token_id]], "", "")
all_eos_tokens.add(eos_token)
stop_tokens = list()
for eos_token in all_eos_tokens:
content += f'PARAMETER stop "{eos_token}"\n'
return content
stop_tokens.append(eos_token)
params = {'stop': stop_tokens}
return TemplateLoader._format_return(template_lines, params, split)
@staticmethod
def _read_content_from_url(url):
response = requests.get(url)
response.raise_for_status()
try:
response = requests.get(url)
response.raise_for_status()
except requests.exceptions.HTTPError as e:
return None
content = response.content
return content.decode('utf-8')

View File

@@ -293,6 +293,10 @@ class ScienceTasks(object):
protein_structure = 'protein-structure'
class Other(object):
other = 'other'
class TasksIODescriptions(object):
image_to_image = 'image_to_image',
images_to_image = 'images_to_image',
@@ -310,7 +314,8 @@ class TasksIODescriptions(object):
efficient_diffusion_tuning = 'efficient_diffusion_tuning'
class Tasks(CVTasks, NLPTasks, AudioTasks, MultiModalTasks, ScienceTasks):
class Tasks(CVTasks, NLPTasks, AudioTasks, MultiModalTasks, ScienceTasks,
Other):
""" Names for tasks supported by modelscope.
Holds the standard task name to use for identifying different tasks.

View File

@@ -22,15 +22,9 @@ def create_model_if_not_exist(
model_id: str,
chinese_name: str,
visibility: Optional[int] = ModelVisibility.PUBLIC,
license: Optional[str] = Licenses.APACHE_V2,
revision: Optional[str] = DEFAULT_MODEL_REVISION):
exists = True
try:
api.get_model(model_id=model_id, revision=revision)
except HTTPError:
exists = False
if exists:
print(f'model {model_id} already exists, skip creation.')
license: Optional[str] = Licenses.APACHE_V2):
if api.repo_exists(model_id):
logger.info(f'model {model_id} already exists, skip creation.')
return False
else:
api.create_model(
@@ -39,7 +33,7 @@ def create_model_if_not_exist(
license=license,
chinese_name=chinese_name,
)
print(f'model {model_id} successfully created.')
logger.info(f'model {model_id} successfully created.')
return True

View File

@@ -17,7 +17,7 @@ sacremoses>=0.0.41
scikit_learn
sentencepiece
seqeval
spacy>=2.3.5
spacy>=2.3.5,<=3.7.0
stanza
subword_nmt>=0.3.8
termcolor

View File

@@ -6,7 +6,7 @@ from modelscope.hub.api import HubApi
from modelscope.utils.hub import create_model_if_not_exist
# note this is temporary before official account management is ready
YOUR_ACCESS_TOKEN = 'token'
YOUR_ACCESS_TOKEN = 'Get SDK token from https://www.modelscope.cn/my/myaccesstoken'
class HubExampleTest(unittest.TestCase):
@@ -18,10 +18,10 @@ class HubExampleTest(unittest.TestCase):
@unittest.skip('to be used for local test only')
def test_example_model_creation(self):
# ATTENTION:change to proper model names before use
model_name = 'cv_unet_person-image-cartoon_compound-models'
model_chinese_name = '达摩卡通化模型'
model_org = 'damo'
model_id = '%s/%s' % (model_org, model_name)
model_name = 'model-name'
model_chinese_name = '我的测试模型'
model_owner = 'iic'
model_id = '%s/%s' % (model_owner, model_name)
created = create_model_if_not_exist(self.api, model_id,
model_chinese_name)
if not created:

View File

@@ -47,6 +47,12 @@ class HubUploadTest(unittest.TestCase):
except Exception:
pass
def test_repo_exist(self):
res = self.api.repo_exists('Qwen/Qwen2.5-7B-Instruct')
self.assertTrue(res)
res = self.api.repo_exists('Qwen/not-a-repo')
self.assertFalse(res)
def test_upload_exits_repo_master(self):
logger.info('basic test for upload!')
self.api.login(TEST_ACCESS_TOKEN1)

View File

@@ -41,12 +41,16 @@ class TextErrorCorrectionTest(unittest.TestCase):
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_run_with_model_name_batch(self):
run_kwargs = {'batch_size': 2}
pipeline_ins = pipeline(
task=Tasks.text_error_correction, model=self.model_id)
print(
'batch: ',
pipeline_ins([self.input, self.input_2, self.input_3], run_kwargs))
sents = [
self.input, self.input_2, self.input_3, self.input_4,
self.input_law
]
rs1 = pipeline_ins(sents, batch_size=2)
rs2 = pipeline_ins(sents)
print('batch: ', rs1, rs2)
self.assertEqual(rs1, rs2)
@unittest.skipUnless(test_level() >= 1, 'skip test in current test level')
def test_run_with_model_from_modelhub(self):

View File

@@ -7,6 +7,12 @@ from modelscope.preprocessors.templates.loader import TemplateLoader
from modelscope.utils.test_utils import test_level
def _test_check_tmpl_type(model, tmpl_type):
ollama, info = TemplateLoader.to_ollama(model, debug=True)
assert info.__dict__.get('modelfile_prefix').split(
'/')[-1] == tmpl_type, info
class TestToOllama(unittest.TestCase):
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
@@ -39,7 +45,7 @@ class TestToOllama(unittest.TestCase):
self.assertTrue(template.template_type == TemplateType.deepseek)
template = TemplateLoader.load_by_model_id(
'deepseek-ai/DeepSeek-Coder-V2-Instruct')
'deepseek-ai/DeepSeek-V2-Lite-Chat')
self.assertTrue(template.template_type == TemplateType.deepseek2)
template = TemplateLoader.load_by_model_id('01ai/Yi-1.5-9B-Chat')
@@ -53,11 +59,11 @@ class TestToOllama(unittest.TestCase):
self.assertTrue(template.template_type == TemplateType.gemma)
template = TemplateLoader.load_by_model_id('AI-ModelScope/gemma-2b')
self.assertTrue(template is None)
self.assertTrue(template.template_type == TemplateType.gemma)
template = TemplateLoader.load_by_model_id(
'AI-ModelScope/gemma-2b-instruct')
self.assertTrue(template is None)
self.assertTrue(template.template_type == TemplateType.gemma)
template = TemplateLoader.load_by_model_id(
'AI-ModelScope/gemma2-2b-instruct')
@@ -108,6 +114,187 @@ class TestToOllama(unittest.TestCase):
ollama = TemplateLoader.to_ollama(
'01ai/Yi-1.5-9B-Chat', ignore_oss_model_file=True)
self.assertTrue(ollama is not None)
ollama = TemplateLoader.to_ollama(
'QuantFactory/Mistral-7B-Instruct-v0.1-GGUF',
ignore_oss_model_file=True)
self.assertTrue(ollama is not None)
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_check_template_type(self):
_test_check_tmpl_type('LLM-Research/Meta-Llama-3.2-8B-Instruct-GGUF',
'llama3.2')
_test_check_tmpl_type('LLM-Research/Meta-Llama-3.1-8B-Instruct-GGUF',
'llama3.1')
_test_check_tmpl_type('LLM-Research/Meta-Llama-3-8B-Instruct-GGUF',
'llama3')
_test_check_tmpl_type(
'LLM-Research/Llama-3-8B-Instruct-Gradient-4194k-GGUF',
'llama3-gradient')
_test_check_tmpl_type('QuantFactory/Llama-3-Groq-8B-Tool-Use-GGUF',
'llama3-groq-tool-use')
_test_check_tmpl_type('QuantFactory/Llama3-ChatQA-1.5-8B-GGUF',
'llama3-chatqa')
_test_check_tmpl_type('SinpxAI/Llama2-Chinese-7B-Chat-GGUF',
'llama2-chinese')
_test_check_tmpl_type('QuantFactory/dolphin-2.9-llama3-70b-GGUF',
'dolphin-llama3')
_test_check_tmpl_type('AI-ModelScope/llava-llama-3-8b-v1_1-gguf',
'llava-llama3')
_test_check_tmpl_type('Xorbits/Llama-2-7b-Chat-GGUF', 'llama2')
_test_check_tmpl_type('QuantFactory/MathCoder2-CodeLlama-7B-GGUF',
'codellama')
_test_check_tmpl_type('QuantFactory/TinyLlama-1.1B-Chat-v1.0-GGUF',
'tinyllama')
_test_check_tmpl_type('AI-ModelScope/LLaMA-Pro-8B-Instruct',
'llama-pro')
_test_check_tmpl_type('LLM-Research/Llama-Guard-3-8B', 'llama-guard3')
_test_check_tmpl_type('Qwen/Qwen2.5-3B-Instruct-GGUF', 'qwen2.5')
_test_check_tmpl_type('Xorbits/Qwen-14B-Chat-GGUF', 'qwen')
_test_check_tmpl_type('QuantFactory/Qwen2-7B-GGUF', 'qwen2')
_test_check_tmpl_type('QuantFactory/Qwen2-Math-7B-GGUF', 'qwen2-math')
_test_check_tmpl_type('Qwen/CodeQwen1.5-7B-Chat-GGUF', 'codeqwen')
_test_check_tmpl_type('Qwen/Qwen2.5-Coder-7B-Instruct-GGUF',
'qwen2.5-coder')
_test_check_tmpl_type('QuantFactory/Gemma-2-Ataraxy-9B-Chat-GGUF',
'gemma2')
_test_check_tmpl_type(
'QuantFactory/Athene-codegemma-2-7b-it-alpaca-v1.1-GGUF',
'codegemma')
_test_check_tmpl_type('QuantFactory/gemma-7b-GGUF', 'gemma')
_test_check_tmpl_type('QuantFactory/shieldgemma-2b-GGUF',
'shieldgemma')
_test_check_tmpl_type(
'ZhaoningLi/laser-dolphin-mixtral-2x7b-dpo.fp16.gguf',
'dolphin-mixtral')
_test_check_tmpl_type('QuantFactory/dolphin-2.1-mistral-7b-GGUF',
'dolphin-mistral')
_test_check_tmpl_type('xtuner/llava-phi-3-mini', 'llava-phi3')
_test_check_tmpl_type('QuantFactory/Phi-3.5-mini-instruct-GGUF',
'phi3.5')
_test_check_tmpl_type('AI-ModelScope/Phi-3-medium-128k-instruct-GGUF',
'phi3')
_test_check_tmpl_type('QuantFactory/phi-2-GGUF', 'phi')
_test_check_tmpl_type('alignmentforever/alpaca-Yarn-Mistral-7b-128k',
'yarn-mistral')
_test_check_tmpl_type('LLM-Research/Mistral-Large-Instruct-2407',
'mistral-large')
_test_check_tmpl_type('AI-ModelScope/MistralLite', 'mistrallite')
_test_check_tmpl_type('AI-ModelScope/Mistral-Small-Instruct-2409',
'mistral-small')
_test_check_tmpl_type('LLM-Research/Mistral-Nemo-Instruct-2407-GGUF',
'mistral-nemo')
_test_check_tmpl_type('QuantFactory/Mistral-7B-OpenOrca-GGUF',
'mistral-openorca')
_test_check_tmpl_type('QuantFactory/Mistral-7B-Instruct-v0.1-GGUF',
'mistral')
_test_check_tmpl_type(
'second-state/Nous-Hermes-2-Mixtral-8x7B-SFT-GGUF',
'nous-hermes2-mixtral')
_test_check_tmpl_type('AI-ModelScope/Mixtral-8x22B-v0.1-GGUF',
'mixtral')
_test_check_tmpl_type('QuantFactory/Nemotron-Mini-4B-Instruct-GGUF',
'nemotron-mini')
_test_check_tmpl_type('AI-ModelScope/Nemotron-4-340B-Instruct',
'nemotron')
_test_check_tmpl_type('TIGER-Lab/Mantis-bakllava-7b', 'bakllava')
_test_check_tmpl_type('fireicewolf/llava-v1.6-34B-gguf', 'llava')
_test_check_tmpl_type(
'AI-ModelScope/DeepSeek-Coder-V2-Lite-Instruct-GGUF',
'deepseek-coder-v2')
_test_check_tmpl_type('QuantFactory/deepseek-coder-6.7B-kexer-GGUF',
'deepseek-coder')
_test_check_tmpl_type('deepseek-ai/DeepSeek-V2.5', 'deepseek-v2.5')
_test_check_tmpl_type('deepseek-ai/DeepSeek-V2-Lite-Chat',
'deepseek-v2')
_test_check_tmpl_type('deepseek-ai/deepseek-llm-67b-chat',
'deepseek-llm')
_test_check_tmpl_type('LLM-Research/glm-4-9b-chat-GGUF', 'glm4')
_test_check_tmpl_type('AI-ModelScope/Yi-Coder-9B-Chat-GGUF',
'yi-coder')
_test_check_tmpl_type('01ai/Yi-1.5-9B-Chat', 'yi')
_test_check_tmpl_type('AI-ModelScope/c4ai-command-r-plus',
'command-r-plus')
_test_check_tmpl_type('AI-ModelScope/c4ai-command-r-v01', 'command-r')
_test_check_tmpl_type('LLM-Research/codegeex4-all-9b-GGUF',
'codegeex4')
_test_check_tmpl_type('a7823093/Wizard-Vicuna-13B-Uncensored-HF',
'wizard-vicuna-uncensored')
_test_check_tmpl_type('AI-ModelScope/WizardLM-2-8x22B-GGUF',
'wizardlm2')
_test_check_tmpl_type('AI-ModelScope/WizardCoder-Python-34B-V1.0',
'wizardcoder')
_test_check_tmpl_type('AI-ModelScope/WizardMath-7B-V1.0',
'wizard-math')
_test_check_tmpl_type('AI-ModelScope/WizardLM-7B-V1.0', 'wizardlm')
_test_check_tmpl_type('QuantFactory/vicuna-13b-v1.5-GGUF', 'vicuna')
_test_check_tmpl_type('QuantFactory/Nous-Hermes-2-SOLAR-10.7B-GGUF',
'nous-hermes2')
_test_check_tmpl_type('QuantFactory/stable-code-instruct-3b-GGUF',
'stable-code')
_test_check_tmpl_type('AI-ModelScope/stablelm-tuned-alpha-7b',
'stablelm2')
_test_check_tmpl_type('QuantFactory/internlm2-chat-7b-GGUF',
'internlm2')
_test_check_tmpl_type('openbmb/MiniCPM-V-2-gguf', 'minicpm-v')
_test_check_tmpl_type('QuantFactory/Codestral-22B-v0.1-GGUF',
'codestral')
_test_check_tmpl_type('AI-ModelScope/nomic-embed-text-v1',
'nomic-embed-text')
_test_check_tmpl_type('AI-ModelScope/mxbai-embed-large-v1',
'mxbai-embed-large')
_test_check_tmpl_type('AI-ModelScope/starcoder2-7b', 'starcoder2')
_test_check_tmpl_type('QwenCollection/orca_mini_v7_72b', 'orca-mini')
_test_check_tmpl_type('modelscope/zephyr-7b-beta', 'zephyr')
_test_check_tmpl_type('LLM-Research/snowflake-arctic-embed-m',
'snowflake-arctic-embed')
_test_check_tmpl_type('TabbyML/StarCoder-1B', 'starcoder')
_test_check_tmpl_type('QuantFactory/granite-8b-code-instruct-4k-GGUF',
'granite-code')
_test_check_tmpl_type('AI-ModelScope/all-MiniLM-L6-v2', 'all-minilm')
_test_check_tmpl_type('QuantFactory/openchat-3.6-8b-20240522-GGUF',
'openchat')
_test_check_tmpl_type('AI-ModelScope/aya-101', 'aya')
_test_check_tmpl_type('LLM-Research/OpenHermes-2.5-Mistral-7B',
'openhermes')
_test_check_tmpl_type('AI-ModelScope/Reflection-Llama-3.1-70B',
'reflection')
_test_check_tmpl_type('AI-ModelScope/neural-chat-7b-v3-1',
'neural-chat')
_test_check_tmpl_type('AI-ModelScope/moondream1', 'moondream')
_test_check_tmpl_type('AI-ModelScope/Xwin-LM-70B-V0.1', 'xwinlm')
_test_check_tmpl_type(
'QuantFactory/smollm-360M-instruct-add-basics-GGUF', 'smollm')
_test_check_tmpl_type('AI-ModelScope/sqlcoder-7b-2', 'sqlcoder')
_test_check_tmpl_type('LLM-Research/Starling-LM-7B-beta',
'starling-lm')
_test_check_tmpl_type('AI-ModelScope/falcon-7b', 'falcon')
_test_check_tmpl_type('QuantFactory/SOLAR-10.7B-v1.0-GGUF', 'solar')
_test_check_tmpl_type('AI-ModelScope/Orca-2-13b', 'orca2')
_test_check_tmpl_type('AI-ModelScope/Hermes-3-Llama-3.1-8B', 'hermes3')
_test_check_tmpl_type('QuantFactory/meditron-7b-GGUF', 'meditron')
_test_check_tmpl_type('QuantFactory/NexusRaven-V2-13B-GGUF',
'nexusraven')
_test_check_tmpl_type('davideuler/Magicoder-s-DS-6.7B-GGUF',
'magicoder')
_test_check_tmpl_type('ZhejiangLab-LifeScience/falcon-assistant-2',
'falcon2')
_test_check_tmpl_type('Xorbits/bge-m3', 'bge-m3')
_test_check_tmpl_type('AI-ModelScope/notux-8x7b-v1', 'notux')
_test_check_tmpl_type('AI-ModelScope/OpenOrca-Platypus2-13B',
'open-orca-platypus2')
_test_check_tmpl_type('QuantFactory/notus-7b-v1-GGUF', 'notus')
_test_check_tmpl_type('AI-ModelScope/mathstral-7B-v0.1', 'mathstral')
_test_check_tmpl_type('AI-ModelScope/solar-pro-preview-instruct',
'solar-pro')
_test_check_tmpl_type('AI-ModelScope/dbrx-instruct', 'dbrx')
_test_check_tmpl_type('QuantFactory/NuExtract-GGUF', 'nuextract')
_test_check_tmpl_type('QuantFactory/reader-lm-1.5b-GGUF', 'reader-lm')
_test_check_tmpl_type(
'SDXL-LoRA/KappaNeuro-alfred-augustus-glendening-style', 'alfred')
_test_check_tmpl_type('AI-ModelScope/bge-large-zh-v1.5', 'bge-large')
_test_check_tmpl_type(
'Ceceliachenen/paraphrase-multilingual-MiniLM-L12-v2',
'paraphrase-multilingual')
if __name__ == '__main__':