mirror of
https://github.com/modelscope/modelscope.git
synced 2025-12-25 12:39:25 +01:00
Merge pull request #30 from modelscope/merge_master_internal_1118
Merge master internal 1118
This commit is contained in:
@@ -1,6 +1,3 @@
|
||||
echo "Testing envs"
|
||||
printenv
|
||||
echo "ENV END"
|
||||
if [ "$MODELSCOPE_SDK_DEBUG" == "True" ]; then
|
||||
pip install -r requirements/tests.txt
|
||||
git config --global --add safe.directory /Maas-lib
|
||||
@@ -28,7 +25,7 @@ if [ "$MODELSCOPE_SDK_DEBUG" == "True" ]; then
|
||||
awk -F: '/^[^#]/ { print $1 }' requirements/multi-modal.txt | xargs -n 1 pip install -f https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.html
|
||||
awk -F: '/^[^#]/ { print $1 }' requirements/nlp.txt | xargs -n 1 pip install -f https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.html
|
||||
awk -F: '/^[^#]/ { print $1 }' requirements/science.txt | xargs -n 1 pip install -f https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.html
|
||||
pip install -r requirements/tests.txt
|
||||
|
||||
# test with install
|
||||
python setup.py install
|
||||
else
|
||||
|
||||
@@ -3,30 +3,32 @@ MODELSCOPE_CACHE_DIR_IN_CONTAINER=/modelscope_cache
|
||||
CODE_DIR=$PWD
|
||||
CODE_DIR_IN_CONTAINER=/Maas-lib
|
||||
echo "$USER"
|
||||
gpus='7 6 5 4 3 2 1 0'
|
||||
cpu_sets='0-7 8-15 16-23 24-30 31-37 38-44 45-51 52-58'
|
||||
gpus='0,1 2,3 4,5 6,7'
|
||||
cpu_sets='45-58 31-44 16-30 0-15'
|
||||
cpu_sets_arr=($cpu_sets)
|
||||
is_get_file_lock=false
|
||||
# export RUN_CASE_COMMAND='python tests/run.py --run_config tests/run_config.yaml'
|
||||
CI_COMMAND=${CI_COMMAND:-bash .dev_scripts/ci_container_test.sh $RUN_CASE_BASE_COMMAND}
|
||||
CI_COMMAND='bash .dev_scripts/ci_container_test.sh python tests/run.py --parallel 2 --run_config tests/run_config.yaml'
|
||||
echo "ci command: $CI_COMMAND"
|
||||
idx=0
|
||||
for gpu in $gpus
|
||||
do
|
||||
exec {lock_fd}>"/tmp/gpu$gpu" || exit 1
|
||||
flock -n "$lock_fd" || { echo "WARN: gpu $gpu is in use!" >&2; continue; }
|
||||
flock -n "$lock_fd" || { echo "WARN: gpu $gpu is in use!" >&2; idx=$((idx+1)); continue; }
|
||||
echo "get gpu lock $gpu"
|
||||
CONTAINER_NAME="modelscope-ci-$gpu"
|
||||
|
||||
CONTAINER_NAME="modelscope-ci-$idx"
|
||||
let is_get_file_lock=true
|
||||
|
||||
# pull image if there are update
|
||||
docker pull ${IMAGE_NAME}:${IMAGE_VERSION}
|
||||
if [ "$MODELSCOPE_SDK_DEBUG" == "True" ]; then
|
||||
echo 'debugging'
|
||||
docker run --rm --name $CONTAINER_NAME --shm-size=16gb \
|
||||
--cpuset-cpus=${cpu_sets_arr[$gpu]} \
|
||||
--gpus="device=$gpu" \
|
||||
--cpuset-cpus=${cpu_sets_arr[$idx]} \
|
||||
--gpus='"'"device=$gpu"'"' \
|
||||
-v $CODE_DIR:$CODE_DIR_IN_CONTAINER \
|
||||
-v $MODELSCOPE_CACHE:$MODELSCOPE_CACHE_DIR_IN_CONTAINER \
|
||||
-v $MODELSCOPE_HOME_CACHE/$gpu:/root \
|
||||
-v $MODELSCOPE_HOME_CACHE/$idx:/root \
|
||||
-v /home/admin/pre-commit:/home/admin/pre-commit \
|
||||
-e CI_TEST=True \
|
||||
-e TEST_LEVEL=$TEST_LEVEL \
|
||||
@@ -41,16 +43,15 @@ do
|
||||
-e TEST_UPLOAD_MS_TOKEN=$TEST_UPLOAD_MS_TOKEN \
|
||||
-e MODEL_TAG_URL=$MODEL_TAG_URL \
|
||||
--workdir=$CODE_DIR_IN_CONTAINER \
|
||||
--net host \
|
||||
${IMAGE_NAME}:${IMAGE_VERSION} \
|
||||
$CI_COMMAND
|
||||
else
|
||||
docker run --rm --name $CONTAINER_NAME --shm-size=16gb \
|
||||
--cpuset-cpus=${cpu_sets_arr[$gpu]} \
|
||||
--gpus="device=$gpu" \
|
||||
--cpuset-cpus=${cpu_sets_arr[$idx]} \
|
||||
--gpus='"'"device=$gpu"'"' \
|
||||
-v $CODE_DIR:$CODE_DIR_IN_CONTAINER \
|
||||
-v $MODELSCOPE_CACHE:$MODELSCOPE_CACHE_DIR_IN_CONTAINER \
|
||||
-v $MODELSCOPE_HOME_CACHE/$gpu:/root \
|
||||
-v $MODELSCOPE_HOME_CACHE/$idx:/root \
|
||||
-v /home/admin/pre-commit:/home/admin/pre-commit \
|
||||
-e CI_TEST=True \
|
||||
-e TEST_LEVEL=$TEST_LEVEL \
|
||||
@@ -64,7 +65,6 @@ do
|
||||
-e TEST_UPLOAD_MS_TOKEN=$TEST_UPLOAD_MS_TOKEN \
|
||||
-e MODEL_TAG_URL=$MODEL_TAG_URL \
|
||||
--workdir=$CODE_DIR_IN_CONTAINER \
|
||||
--net host \
|
||||
${IMAGE_NAME}:${IMAGE_VERSION} \
|
||||
$CI_COMMAND
|
||||
fi
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
repos:
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
- repo: https://github.com/pycqa/flake8.git
|
||||
rev: 4.0.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
|
||||
@@ -23,9 +23,10 @@ from modelscope.hub.constants import (API_RESPONSE_FIELD_DATA,
|
||||
API_RESPONSE_FIELD_MESSAGE,
|
||||
API_RESPONSE_FIELD_USERNAME,
|
||||
DEFAULT_CREDENTIALS_PATH,
|
||||
MODELSCOPE_ENVIRONMENT,
|
||||
MODELSCOPE_USERNAME, ONE_YEAR_SECONDS,
|
||||
Licenses, ModelVisibility)
|
||||
MODELSCOPE_CLOUD_ENVIRONMENT,
|
||||
MODELSCOPE_CLOUD_USERNAME,
|
||||
ONE_YEAR_SECONDS, Licenses,
|
||||
ModelVisibility)
|
||||
from modelscope.hub.errors import (InvalidParameter, NotExistError,
|
||||
NotLoginException, NoValidRevisionError,
|
||||
RequestError, datahub_raise_on_error,
|
||||
@@ -653,10 +654,10 @@ class HubApi:
|
||||
# get channel and user_name
|
||||
channel = DownloadChannel.LOCAL.value
|
||||
user_name = ''
|
||||
if MODELSCOPE_ENVIRONMENT in os.environ:
|
||||
channel = os.environ[MODELSCOPE_ENVIRONMENT]
|
||||
if MODELSCOPE_USERNAME in os.environ:
|
||||
user_name = os.environ[MODELSCOPE_USERNAME]
|
||||
if MODELSCOPE_CLOUD_ENVIRONMENT in os.environ:
|
||||
channel = os.environ[MODELSCOPE_CLOUD_ENVIRONMENT]
|
||||
if MODELSCOPE_CLOUD_USERNAME in os.environ:
|
||||
user_name = os.environ[MODELSCOPE_CLOUD_USERNAME]
|
||||
|
||||
url = f'{self.endpoint}/api/v1/datasets/{namespace}/{dataset_name}/download/uv/{channel}?user={user_name}'
|
||||
cookies = ModelScopeConfig.get_cookies()
|
||||
@@ -777,12 +778,15 @@ class ModelScopeConfig:
|
||||
Returns:
|
||||
The formatted user-agent string.
|
||||
"""
|
||||
|
||||
# include some more telemetrics when executing in dedicated
|
||||
# cloud containers
|
||||
env = 'custom'
|
||||
if MODELSCOPE_ENVIRONMENT in os.environ:
|
||||
env = os.environ[MODELSCOPE_ENVIRONMENT]
|
||||
if MODELSCOPE_CLOUD_ENVIRONMENT in os.environ:
|
||||
env = os.environ[MODELSCOPE_CLOUD_ENVIRONMENT]
|
||||
user_name = 'unknown'
|
||||
if MODELSCOPE_USERNAME in os.environ:
|
||||
user_name = os.environ[MODELSCOPE_USERNAME]
|
||||
if MODELSCOPE_CLOUD_USERNAME in os.environ:
|
||||
user_name = os.environ[MODELSCOPE_CLOUD_USERNAME]
|
||||
|
||||
ua = 'modelscope/%s; python/%s; session_id/%s; platform/%s; processor/%s; env/%s; user/%s' % (
|
||||
__version__,
|
||||
|
||||
@@ -16,9 +16,9 @@ API_RESPONSE_FIELD_GIT_ACCESS_TOKEN = 'AccessToken'
|
||||
API_RESPONSE_FIELD_USERNAME = 'Username'
|
||||
API_RESPONSE_FIELD_EMAIL = 'Email'
|
||||
API_RESPONSE_FIELD_MESSAGE = 'Message'
|
||||
MODELSCOPE_ENVIRONMENT = 'MODELSCOPE_ENVIRONMENT'
|
||||
MODELSCOPE_CLOUD_ENVIRONMENT = 'MODELSCOPE_ENVIRONMENT'
|
||||
MODELSCOPE_CLOUD_USERNAME = 'MODELSCOPE_USERNAME'
|
||||
MODELSCOPE_SDK_DEBUG = 'MODELSCOPE_SDK_DEBUG'
|
||||
MODELSCOPE_USERNAME = 'MODELSCOPE_USERNAME'
|
||||
ONE_YEAR_SECONDS = 24 * 365 * 60 * 60
|
||||
|
||||
|
||||
|
||||
@@ -87,16 +87,3 @@ def file_integrity_validation(file_path, expected_sha256):
|
||||
msg = 'File %s integrity check failed, the download may be incomplete, please try again.' % file_path
|
||||
logger.error(msg)
|
||||
raise FileIntegrityError(msg)
|
||||
|
||||
|
||||
def create_library_statistics(method: str, name: str, cn_name: Optional[str]):
|
||||
try:
|
||||
from modelscope.hub.api import ModelScopeConfig
|
||||
path = f'{get_endpoint()}/api/v1/statistics/library'
|
||||
headers = {'user-agent': ModelScopeConfig.get_user_agent()}
|
||||
params = {'Method': method, 'Name': name, 'CnName': cn_name}
|
||||
r = requests.post(path, params=params, headers=headers)
|
||||
r.raise_for_status()
|
||||
except Exception:
|
||||
pass
|
||||
return
|
||||
|
||||
@@ -54,7 +54,8 @@ class FSMNSeleNetV2Decorator(TorchModel):
|
||||
)
|
||||
|
||||
def __del__(self):
|
||||
self.tmp_dir.cleanup()
|
||||
if hasattr(self, 'tmp_dir'):
|
||||
self.tmp_dir.cleanup()
|
||||
|
||||
def forward(self, input: Dict[str, Tensor]) -> Dict[str, Tensor]:
|
||||
return self.model.forward(input)
|
||||
|
||||
@@ -20,7 +20,6 @@ class MogFaceDetector(TorchModel):
|
||||
|
||||
def __init__(self, model_path, device='cuda'):
|
||||
super().__init__(model_path)
|
||||
torch.set_grad_enabled(False)
|
||||
cudnn.benchmark = True
|
||||
self.model_path = model_path
|
||||
self.device = device
|
||||
|
||||
@@ -21,7 +21,6 @@ class MtcnnFaceDetector(TorchModel):
|
||||
|
||||
def __init__(self, model_path, device='cuda'):
|
||||
super().__init__(model_path)
|
||||
torch.set_grad_enabled(False)
|
||||
cudnn.benchmark = True
|
||||
self.model_path = model_path
|
||||
self.device = device
|
||||
|
||||
@@ -18,7 +18,6 @@ class RetinaFaceDetection(TorchModel):
|
||||
|
||||
def __init__(self, model_path, device='cuda'):
|
||||
super().__init__(model_path)
|
||||
torch.set_grad_enabled(False)
|
||||
cudnn.benchmark = True
|
||||
self.model_path = model_path
|
||||
self.cfg = Config.from_file(
|
||||
|
||||
@@ -24,7 +24,6 @@ class UlfdFaceDetector(TorchModel):
|
||||
|
||||
def __init__(self, model_path, device='cuda'):
|
||||
super().__init__(model_path)
|
||||
torch.set_grad_enabled(False)
|
||||
cudnn.benchmark = True
|
||||
self.model_path = model_path
|
||||
self.device = device
|
||||
|
||||
@@ -24,7 +24,6 @@ class FacialExpressionRecognition(TorchModel):
|
||||
|
||||
def __init__(self, model_path, device='cuda'):
|
||||
super().__init__(model_path)
|
||||
torch.set_grad_enabled(False)
|
||||
cudnn.benchmark = True
|
||||
self.model_path = model_path
|
||||
self.device = device
|
||||
|
||||
@@ -31,7 +31,6 @@ cfg_re50 = {
|
||||
class RetinaFaceDetection(object):
|
||||
|
||||
def __init__(self, model_path, device='cuda'):
|
||||
torch.set_grad_enabled(False)
|
||||
cudnn.benchmark = True
|
||||
self.model_path = model_path
|
||||
self.device = device
|
||||
|
||||
@@ -7,6 +7,7 @@ import time
|
||||
|
||||
import cv2
|
||||
import json
|
||||
import numpy as np
|
||||
import torch
|
||||
from tqdm import tqdm
|
||||
|
||||
@@ -87,13 +88,17 @@ class RealtimeVideoDetector(TorchModel):
|
||||
self.nmsthre,
|
||||
class_agnostic=True)
|
||||
|
||||
if len(outputs) == 1:
|
||||
if len(outputs) == 1 and (outputs[0] is not None):
|
||||
bboxes = outputs[0][:, 0:4].cpu().numpy() / self.ratio
|
||||
scores = outputs[0][:, 5].cpu().numpy()
|
||||
labels = outputs[0][:, 6].cpu().int().numpy()
|
||||
pred_label_names = []
|
||||
for lab in labels:
|
||||
pred_label_names.append(self.label_mapping[lab])
|
||||
else:
|
||||
bboxes = np.asarray([])
|
||||
scores = np.asarray([])
|
||||
pred_label_names = np.asarray([])
|
||||
|
||||
return bboxes, scores, pred_label_names
|
||||
|
||||
|
||||
@@ -31,7 +31,10 @@ class ReferringVideoObjectSegmentation(TorchModel):
|
||||
|
||||
config_path = osp.join(model_dir, ModelFile.CONFIGURATION)
|
||||
self.cfg = Config.from_file(config_path)
|
||||
self.model = MTTR(**self.cfg.model)
|
||||
transformer_cfg_dir = osp.join(model_dir, 'transformer_cfg_dir')
|
||||
|
||||
self.model = MTTR(
|
||||
transformer_cfg_dir=transformer_cfg_dir, **self.cfg.model)
|
||||
|
||||
model_path = osp.join(model_dir, ModelFile.TORCH_MODEL_FILE)
|
||||
params_dict = torch.load(model_path, map_location='cpu')
|
||||
|
||||
@@ -19,6 +19,7 @@ class MTTR(nn.Module):
|
||||
num_queries,
|
||||
mask_kernels_dim=8,
|
||||
aux_loss=False,
|
||||
transformer_cfg_dir=None,
|
||||
**kwargs):
|
||||
"""
|
||||
Parameters:
|
||||
@@ -29,7 +30,9 @@ class MTTR(nn.Module):
|
||||
"""
|
||||
super().__init__()
|
||||
self.backbone = init_backbone(**kwargs)
|
||||
self.transformer = MultimodalTransformer(**kwargs)
|
||||
assert transformer_cfg_dir is not None
|
||||
self.transformer = MultimodalTransformer(
|
||||
transformer_cfg_dir=transformer_cfg_dir, **kwargs)
|
||||
d_model = self.transformer.d_model
|
||||
self.is_referred_head = nn.Linear(
|
||||
d_model,
|
||||
|
||||
@@ -26,6 +26,7 @@ class MultimodalTransformer(nn.Module):
|
||||
num_decoder_layers=3,
|
||||
text_encoder_type='roberta-base',
|
||||
freeze_text_encoder=True,
|
||||
transformer_cfg_dir=None,
|
||||
**kwargs):
|
||||
super().__init__()
|
||||
self.d_model = kwargs['d_model']
|
||||
@@ -40,10 +41,12 @@ class MultimodalTransformer(nn.Module):
|
||||
self.pos_encoder_2d = PositionEmbeddingSine2D()
|
||||
self._reset_parameters()
|
||||
|
||||
self.text_encoder = RobertaModel.from_pretrained(text_encoder_type)
|
||||
if text_encoder_type != 'roberta-base':
|
||||
transformer_cfg_dir = text_encoder_type
|
||||
self.text_encoder = RobertaModel.from_pretrained(transformer_cfg_dir)
|
||||
self.text_encoder.pooler = None # this pooler is never used, this is a hack to avoid DDP problems...
|
||||
self.tokenizer = RobertaTokenizerFast.from_pretrained(
|
||||
text_encoder_type)
|
||||
transformer_cfg_dir)
|
||||
self.freeze_text_encoder = freeze_text_encoder
|
||||
if freeze_text_encoder:
|
||||
for p in self.text_encoder.parameters():
|
||||
|
||||
@@ -188,11 +188,13 @@ class Worker(threading.Thread):
|
||||
|
||||
|
||||
class KWSDataLoader:
|
||||
"""
|
||||
dataset: the dataset reference
|
||||
batchsize: data batch size
|
||||
numworkers: no. of workers
|
||||
prefetch: prefetch factor
|
||||
""" Load and organize audio data with multiple threads
|
||||
|
||||
Args:
|
||||
dataset: the dataset reference
|
||||
batchsize: data batch size
|
||||
numworkers: no. of workers
|
||||
prefetch: prefetch factor
|
||||
"""
|
||||
|
||||
def __init__(self, dataset, batchsize, numworkers, prefetch=2):
|
||||
@@ -202,7 +204,7 @@ class KWSDataLoader:
|
||||
self.isrun = True
|
||||
|
||||
# data queue
|
||||
self.pool = queue.Queue(batchsize * prefetch)
|
||||
self.pool = queue.Queue(numworkers * prefetch)
|
||||
|
||||
# initialize workers
|
||||
self.workerlist = []
|
||||
@@ -270,11 +272,11 @@ class KWSDataLoader:
|
||||
w.stopWorker()
|
||||
|
||||
while not self.pool.empty():
|
||||
self.pool.get(block=True, timeout=0.001)
|
||||
self.pool.get(block=True, timeout=0.01)
|
||||
|
||||
# wait workers terminated
|
||||
for w in self.workerlist:
|
||||
while not self.pool.empty():
|
||||
self.pool.get(block=True, timeout=0.001)
|
||||
self.pool.get(block=True, timeout=0.01)
|
||||
w.join()
|
||||
logger.info('KWSDataLoader: All worker stopped.')
|
||||
|
||||
@@ -10,7 +10,6 @@ from typing import Any, Dict, Generator, List, Mapping, Union
|
||||
|
||||
import numpy as np
|
||||
|
||||
from modelscope.hub.utils.utils import create_library_statistics
|
||||
from modelscope.models.base import Model
|
||||
from modelscope.msdatasets import MsDataset
|
||||
from modelscope.outputs import TASK_OUTPUTS
|
||||
@@ -152,9 +151,6 @@ class Pipeline(ABC):
|
||||
**kwargs) -> Union[Dict[str, Any], Generator]:
|
||||
# model provider should leave it as it is
|
||||
# modelscope library developer will handle this function
|
||||
for single_model in self.models:
|
||||
if hasattr(single_model, 'name'):
|
||||
create_library_statistics('pipeline', single_model.name, None)
|
||||
# place model to cpu or gpu
|
||||
if (self.model or (self.has_multiple_models and self.models[0])):
|
||||
if not self._model_prepare:
|
||||
|
||||
@@ -92,6 +92,8 @@ class NamedEntityRecognitionPipeline(Pipeline):
|
||||
offset_mapping = [x.cpu().tolist() for x in inputs['offset_mapping']]
|
||||
|
||||
labels = [self.id2label[x] for x in predictions]
|
||||
if len(labels) > len(offset_mapping):
|
||||
labels = labels[1:-1]
|
||||
chunks = []
|
||||
chunk = {}
|
||||
for label, offsets in zip(labels, offset_mapping):
|
||||
@@ -104,6 +106,20 @@ class NamedEntityRecognitionPipeline(Pipeline):
|
||||
'start': offsets[0],
|
||||
'end': offsets[1]
|
||||
}
|
||||
if label[0] in 'I':
|
||||
if not chunk:
|
||||
chunk = {
|
||||
'type': label[2:],
|
||||
'start': offsets[0],
|
||||
'end': offsets[1]
|
||||
}
|
||||
if label[0] in 'E':
|
||||
if not chunk:
|
||||
chunk = {
|
||||
'type': label[2:],
|
||||
'start': offsets[0],
|
||||
'end': offsets[1]
|
||||
}
|
||||
if label[0] in 'IES':
|
||||
if chunk:
|
||||
chunk['end'] = offsets[1]
|
||||
@@ -118,15 +134,15 @@ class NamedEntityRecognitionPipeline(Pipeline):
|
||||
chunk['span'] = text[chunk['start']:chunk['end']]
|
||||
chunks.append(chunk)
|
||||
|
||||
# for cws output
|
||||
# for cws outputs
|
||||
if len(chunks) > 0 and chunks[0]['type'] == 'cws':
|
||||
spans = [
|
||||
chunk['span'] for chunk in chunks if chunk['span'].strip()
|
||||
]
|
||||
seg_result = ' '.join(spans)
|
||||
outputs = {OutputKeys.OUTPUT: seg_result, OutputKeys.LABELS: []}
|
||||
outputs = {OutputKeys.OUTPUT: seg_result}
|
||||
|
||||
# for ner outpus
|
||||
# for ner outputs
|
||||
else:
|
||||
outputs = {OutputKeys.OUTPUT: chunks}
|
||||
return outputs
|
||||
|
||||
@@ -95,6 +95,20 @@ class TokenClassificationPipeline(Pipeline):
|
||||
'start': offsets[0],
|
||||
'end': offsets[1]
|
||||
}
|
||||
if label[0] in 'I':
|
||||
if not chunk:
|
||||
chunk = {
|
||||
'type': label[2:],
|
||||
'start': offsets[0],
|
||||
'end': offsets[1]
|
||||
}
|
||||
if label[0] in 'E':
|
||||
if not chunk:
|
||||
chunk = {
|
||||
'type': label[2:],
|
||||
'start': offsets[0],
|
||||
'end': offsets[1]
|
||||
}
|
||||
if label[0] in 'IES':
|
||||
if chunk:
|
||||
chunk['end'] = offsets[1]
|
||||
|
||||
@@ -80,9 +80,12 @@ class WordSegmentationPipeline(Pipeline):
|
||||
Dict[str, str]: the prediction results
|
||||
"""
|
||||
text = inputs['text']
|
||||
logits = inputs[OutputKeys.LOGITS]
|
||||
predictions = torch.argmax(logits[0], dim=-1)
|
||||
logits = torch_nested_numpify(torch_nested_detach(logits))
|
||||
if not hasattr(inputs, 'predictions'):
|
||||
logits = inputs[OutputKeys.LOGITS]
|
||||
predictions = torch.argmax(logits[0], dim=-1)
|
||||
else:
|
||||
predictions = inputs[OutputKeys.PREDICTIONS].squeeze(
|
||||
0).cpu().numpy()
|
||||
predictions = torch_nested_numpify(torch_nested_detach(predictions))
|
||||
offset_mapping = [x.cpu().tolist() for x in inputs['offset_mapping']]
|
||||
|
||||
@@ -101,6 +104,20 @@ class WordSegmentationPipeline(Pipeline):
|
||||
'start': offsets[0],
|
||||
'end': offsets[1]
|
||||
}
|
||||
if label[0] in 'I':
|
||||
if not chunk:
|
||||
chunk = {
|
||||
'type': label[2:],
|
||||
'start': offsets[0],
|
||||
'end': offsets[1]
|
||||
}
|
||||
if label[0] in 'E':
|
||||
if not chunk:
|
||||
chunk = {
|
||||
'type': label[2:],
|
||||
'start': offsets[0],
|
||||
'end': offsets[1]
|
||||
}
|
||||
if label[0] in 'IES':
|
||||
if chunk:
|
||||
chunk['end'] = offsets[1]
|
||||
@@ -123,7 +140,7 @@ class WordSegmentationPipeline(Pipeline):
|
||||
seg_result = ' '.join(spans)
|
||||
outputs = {OutputKeys.OUTPUT: seg_result}
|
||||
|
||||
# for ner output
|
||||
# for ner outputs
|
||||
else:
|
||||
outputs = {OutputKeys.OUTPUT: chunks}
|
||||
return outputs
|
||||
|
||||
@@ -117,8 +117,7 @@ class KWSFarfieldTrainer(BaseTrainer):
|
||||
self._batch_size = dataloader_config.batch_size_per_gpu
|
||||
if 'model_bin' in kwargs:
|
||||
model_bin_file = os.path.join(self.model_dir, kwargs['model_bin'])
|
||||
checkpoint = torch.load(model_bin_file)
|
||||
self.model.load_state_dict(checkpoint)
|
||||
self.model = torch.load(model_bin_file)
|
||||
# build corresponding optimizer and loss function
|
||||
lr = self.cfg.train.optimizer.lr
|
||||
self.optimizer = optim.Adam(self.model.parameters(), lr)
|
||||
@@ -219,7 +218,9 @@ class KWSFarfieldTrainer(BaseTrainer):
|
||||
# check point
|
||||
ckpt_name = 'checkpoint_{:04d}_loss_train_{:.4f}_loss_val_{:.4f}.pth'.format(
|
||||
self._current_epoch, loss_train_epoch, loss_val_epoch)
|
||||
torch.save(self.model, os.path.join(self.work_dir, ckpt_name))
|
||||
save_path = os.path.join(self.work_dir, ckpt_name)
|
||||
logger.info(f'Save model to {save_path}')
|
||||
torch.save(self.model, save_path)
|
||||
# time spent per epoch
|
||||
epochtime = datetime.datetime.now() - epochtime
|
||||
logger.info('Epoch {:04d} time spent: {:.2f} hours'.format(
|
||||
|
||||
@@ -15,7 +15,6 @@ from torch.utils.data.dataloader import default_collate
|
||||
from torch.utils.data.distributed import DistributedSampler
|
||||
|
||||
from modelscope.hub.snapshot_download import snapshot_download
|
||||
from modelscope.hub.utils.utils import create_library_statistics
|
||||
from modelscope.metainfo import Trainers
|
||||
from modelscope.metrics import build_metric, task_default_metrics
|
||||
from modelscope.models.base import Model, TorchModel
|
||||
@@ -437,8 +436,6 @@ class EpochBasedTrainer(BaseTrainer):
|
||||
|
||||
def train(self, checkpoint_path=None, *args, **kwargs):
|
||||
self._mode = ModeKeys.TRAIN
|
||||
if hasattr(self.model, 'name'):
|
||||
create_library_statistics('train', self.model.name, None)
|
||||
|
||||
if self.train_dataset is None:
|
||||
self.train_dataloader = self.get_train_dataloader()
|
||||
@@ -459,8 +456,6 @@ class EpochBasedTrainer(BaseTrainer):
|
||||
self.train_loop(self.train_dataloader)
|
||||
|
||||
def evaluate(self, checkpoint_path=None):
|
||||
if hasattr(self.model, 'name'):
|
||||
create_library_statistics('evaluate', self.model.name, None)
|
||||
if checkpoint_path is not None and os.path.isfile(checkpoint_path):
|
||||
from modelscope.trainers.hooks import CheckpointHook
|
||||
CheckpointHook.load_checkpoint(checkpoint_path, self)
|
||||
|
||||
@@ -43,7 +43,10 @@ def update_conf(origin_config_file, new_config_file, conf_item: [str, str]):
|
||||
def repl(matched):
|
||||
key = matched.group(1)
|
||||
if key in conf_item:
|
||||
return conf_item[key]
|
||||
value = conf_item[key]
|
||||
if not isinstance(value, str):
|
||||
value = str(value)
|
||||
return value
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
136
tests/run.py
136
tests/run.py
@@ -3,11 +3,13 @@
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
import math
|
||||
import multiprocessing
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
import unittest
|
||||
from fnmatch import fnmatch
|
||||
from multiprocessing.managers import BaseManager
|
||||
@@ -158,6 +160,21 @@ def run_command_with_popen(cmd):
|
||||
sys.stdout.write(line)
|
||||
|
||||
|
||||
def async_run_command_with_popen(cmd, device_id):
|
||||
logger.info('Worker id: %s args: %s' % (device_id, cmd))
|
||||
env = os.environ.copy()
|
||||
env['CUDA_VISIBLE_DEVICES'] = '%s' % device_id
|
||||
sub_process = subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
bufsize=1,
|
||||
universal_newlines=True,
|
||||
env=env,
|
||||
encoding='utf8')
|
||||
return sub_process
|
||||
|
||||
|
||||
def save_test_result(df, args):
|
||||
if args.result_dir is not None:
|
||||
file_name = str(int(datetime.datetime.now().timestamp() * 1000))
|
||||
@@ -199,6 +216,108 @@ def install_requirements(requirements):
|
||||
run_command(cmd)
|
||||
|
||||
|
||||
def wait_for_free_worker(workers):
|
||||
while True:
|
||||
for idx, worker in enumerate(workers):
|
||||
if worker is None:
|
||||
logger.info('return free worker: %s' % (idx))
|
||||
return idx
|
||||
if worker.poll() is None: # running, get output
|
||||
for line in iter(worker.stdout.readline, ''):
|
||||
if line != '':
|
||||
sys.stdout.write(line)
|
||||
else:
|
||||
break
|
||||
else: # worker process completed.
|
||||
logger.info('Process end: %s' % (idx))
|
||||
workers[idx] = None
|
||||
return idx
|
||||
time.sleep(0.001)
|
||||
|
||||
|
||||
def wait_for_workers(workers):
|
||||
while True:
|
||||
for idx, worker in enumerate(workers):
|
||||
if worker is None:
|
||||
continue
|
||||
# check worker is completed.
|
||||
if worker.poll() is None:
|
||||
for line in iter(worker.stdout.readline, ''):
|
||||
if line != '':
|
||||
sys.stdout.write(line)
|
||||
else:
|
||||
break
|
||||
else:
|
||||
logger.info('Process idx: %s end!' % (idx))
|
||||
workers[idx] = None
|
||||
|
||||
is_all_completed = True
|
||||
for idx, worker in enumerate(workers):
|
||||
if worker is not None:
|
||||
is_all_completed = False
|
||||
break
|
||||
|
||||
if is_all_completed:
|
||||
logger.info('All sub porcess is completed!')
|
||||
break
|
||||
time.sleep(0.001)
|
||||
|
||||
|
||||
def parallel_run_case_in_env(env_name, env, test_suite_env_map, isolated_cases,
|
||||
result_dir, parallel):
|
||||
logger.info('Running case in env: %s' % env_name)
|
||||
# install requirements and deps # run_config['envs'][env]
|
||||
if 'requirements' in env:
|
||||
install_requirements(env['requirements'])
|
||||
if 'dependencies' in env:
|
||||
install_packages(env['dependencies'])
|
||||
# case worker processes
|
||||
worker_processes = [None] * parallel
|
||||
for test_suite_file in isolated_cases: # run case in subprocess
|
||||
if test_suite_file in test_suite_env_map and test_suite_env_map[
|
||||
test_suite_file] == env_name:
|
||||
cmd = [
|
||||
'python',
|
||||
'tests/run.py',
|
||||
'--pattern',
|
||||
test_suite_file,
|
||||
'--result_dir',
|
||||
result_dir,
|
||||
]
|
||||
worker_idx = wait_for_free_worker(worker_processes)
|
||||
worker_process = async_run_command_with_popen(cmd, worker_idx)
|
||||
os.set_blocking(worker_process.stdout.fileno(), False)
|
||||
worker_processes[worker_idx] = worker_process
|
||||
else:
|
||||
pass # case not in run list.
|
||||
|
||||
# run remain cases in a process.
|
||||
remain_suite_files = []
|
||||
for k, v in test_suite_env_map.items():
|
||||
if k not in isolated_cases and v == env_name:
|
||||
remain_suite_files.append(k)
|
||||
if len(remain_suite_files) == 0:
|
||||
return
|
||||
# roughly split case in parallel
|
||||
part_count = math.ceil(len(remain_suite_files) / parallel)
|
||||
suites_chunks = [
|
||||
remain_suite_files[x:x + part_count]
|
||||
for x in range(0, len(remain_suite_files), part_count)
|
||||
]
|
||||
for suites_chunk in suites_chunks:
|
||||
worker_idx = wait_for_free_worker(worker_processes)
|
||||
cmd = [
|
||||
'python', 'tests/run.py', '--result_dir', result_dir, '--suites'
|
||||
]
|
||||
for suite in suites_chunk:
|
||||
cmd.append(suite)
|
||||
worker_process = async_run_command_with_popen(cmd, worker_idx)
|
||||
os.set_blocking(worker_process.stdout.fileno(), False)
|
||||
worker_processes[worker_idx] = worker_process
|
||||
|
||||
wait_for_workers(worker_processes)
|
||||
|
||||
|
||||
def run_case_in_env(env_name, env, test_suite_env_map, isolated_cases,
|
||||
result_dir):
|
||||
# install requirements and deps # run_config['envs'][env]
|
||||
@@ -264,8 +383,9 @@ def run_in_subprocess(args):
|
||||
|
||||
with tempfile.TemporaryDirectory() as temp_result_dir:
|
||||
for env in set(test_suite_env_map.values()):
|
||||
run_case_in_env(env, run_config['envs'][env], test_suite_env_map,
|
||||
isolated_cases, temp_result_dir)
|
||||
parallel_run_case_in_env(env, run_config['envs'][env],
|
||||
test_suite_env_map, isolated_cases,
|
||||
temp_result_dir, args.parallel)
|
||||
|
||||
result_dfs = []
|
||||
result_path = Path(temp_result_dir)
|
||||
@@ -312,6 +432,10 @@ class TimeCostTextTestResult(TextTestResult):
|
||||
self.stream.writeln(
|
||||
'Test case: %s stop at: %s, cost time: %s(seconds)' %
|
||||
(test.test_full_name, test.stop_time, test.time_cost))
|
||||
if torch.cuda.is_available(
|
||||
) and test.time_cost > 5.0: # print nvidia-smi
|
||||
cmd = ['nvidia-smi']
|
||||
run_command_with_popen(cmd)
|
||||
super(TimeCostTextTestResult, self).stopTest(test)
|
||||
|
||||
def addSuccess(self, test):
|
||||
@@ -383,6 +507,8 @@ def main(args):
|
||||
os.path.abspath(args.test_dir), args.pattern, args.list_tests)
|
||||
if not args.list_tests:
|
||||
result = runner.run(test_suite)
|
||||
logger.info('Running case completed, pid: %s, suites: %s' %
|
||||
(os.getpid(), args.suites))
|
||||
result = collect_test_results(result)
|
||||
df = test_cases_result_to_df(result)
|
||||
if args.result_dir is not None:
|
||||
@@ -417,6 +543,12 @@ if __name__ == '__main__':
|
||||
'--result_dir',
|
||||
default=None,
|
||||
help='Save result to directory, internal use only')
|
||||
parser.add_argument(
|
||||
'--parallel',
|
||||
default=1,
|
||||
type=int,
|
||||
help='Set case parallels, default single process, set with gpu number.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--suites',
|
||||
nargs='*',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# isolate cases in env, we can install different dependencies in each env.
|
||||
isolated: # test cases that may require excessive anmount of GPU memory, which will be executed in dedicagted process.
|
||||
isolated: # test cases that may require excessive anmount of GPU memory or run long time, which will be executed in dedicagted process.
|
||||
- test_text_to_speech.py
|
||||
- test_multi_modal_embedding.py
|
||||
- test_ofa_tasks.py
|
||||
@@ -13,6 +13,33 @@ isolated: # test cases that may require excessive anmount of GPU memory, which
|
||||
- test_movie_scene_segmentation.py
|
||||
- test_image_inpainting.py
|
||||
- test_mglm_text_summarization.py
|
||||
- test_team_transfer_trainer.py
|
||||
- test_image_denoise_trainer.py
|
||||
- test_dialog_intent_trainer.py
|
||||
- test_finetune_mplug.py
|
||||
- test_image_instance_segmentation_trainer.py
|
||||
- test_image_portrait_enhancement_trainer.py
|
||||
- test_translation_trainer.py
|
||||
- test_unifold.py
|
||||
- test_automatic_post_editing.py
|
||||
- test_mplug_tasks.py
|
||||
- test_movie_scene_segmentation.py
|
||||
- test_body_3d_keypoints.py
|
||||
- test_finetune_text_generation.py
|
||||
- test_clip_trainer.py
|
||||
- test_ofa_trainer.py
|
||||
- test_fill_mask.py
|
||||
- test_hand_2d_keypoints.py
|
||||
- test_referring_video_object_segmentation.py
|
||||
- test_easycv_trainer_hand_2d_keypoints.py
|
||||
- test_card_detection_scrfd_trainer.py
|
||||
- test_referring_video_object_segmentation_trainer.py
|
||||
- test_person_image_cartoon.py
|
||||
- test_image_style_transfer.py
|
||||
- test_ocr_detection.py
|
||||
- test_automatic_speech_recognition.py
|
||||
- test_image_matting.py
|
||||
- test_skin_retouching.py
|
||||
|
||||
envs:
|
||||
default: # default env, case not in other env will in default, pytorch.
|
||||
|
||||
@@ -94,7 +94,7 @@ class TestDialogIntentTrainer(unittest.TestCase):
|
||||
cfg.Model.update(config['Model'])
|
||||
if self.debugging:
|
||||
cfg.Trainer.save_checkpoint = False
|
||||
cfg.Trainer.num_epochs = 5
|
||||
cfg.Trainer.num_epochs = 1
|
||||
cfg.Trainer.batch_size_label = 64
|
||||
return cfg
|
||||
|
||||
|
||||
Reference in New Issue
Block a user