xinference 1.10.1__py3-none-any.whl → 1.11.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of xinference might be problematic. Click here for more details.
- xinference/_version.py +3 -3
- xinference/api/restful_api.py +462 -3
- xinference/client/restful/async_restful_client.py +158 -5
- xinference/client/restful/restful_client.py +131 -0
- xinference/core/supervisor.py +12 -0
- xinference/model/audio/model_spec.json +20 -20
- xinference/model/image/model_spec.json +159 -159
- xinference/model/llm/__init__.py +2 -2
- xinference/model/llm/llm_family.json +843 -180
- xinference/model/llm/mlx/distributed_models/core.py +41 -0
- xinference/model/llm/mlx/distributed_models/qwen2.py +1 -2
- xinference/model/llm/sglang/core.py +20 -6
- xinference/model/llm/tool_parsers/qwen_tool_parser.py +29 -4
- xinference/model/llm/transformers/chatglm.py +3 -0
- xinference/model/llm/transformers/core.py +129 -36
- xinference/model/llm/transformers/multimodal/minicpmv45.py +340 -0
- xinference/model/llm/transformers/utils.py +23 -0
- xinference/model/llm/utils.py +37 -24
- xinference/model/llm/vllm/core.py +128 -69
- xinference/model/utils.py +74 -31
- xinference/thirdparty/audiotools/core/audio_signal.py +6 -6
- xinference/thirdparty/fish_speech/fish_speech/text/chn_text_norm/text.py +1 -1
- xinference/thirdparty/melo/text/chinese_mix.py +2 -2
- xinference/types.py +9 -0
- xinference/ui/web/ui/build/asset-manifest.json +3 -3
- xinference/ui/web/ui/build/index.html +1 -1
- xinference/ui/web/ui/build/static/js/{main.d192c4f3.js → main.45e78536.js} +3 -3
- xinference/ui/web/ui/build/static/js/main.45e78536.js.map +1 -0
- xinference/ui/web/ui/node_modules/.cache/babel-loader/ea2a26361204e70cf1018d6990fb6354bed82b3ac69690391e0f100385e7abb7.json +1 -0
- {xinference-1.10.1.dist-info → xinference-1.11.0.dist-info}/METADATA +7 -5
- {xinference-1.10.1.dist-info → xinference-1.11.0.dist-info}/RECORD +36 -35
- xinference/ui/web/ui/build/static/js/main.d192c4f3.js.map +0 -1
- xinference/ui/web/ui/node_modules/.cache/babel-loader/f995a2425dfb0822fd07127f66ffe9b026883bc156b402eb8bd0b83d52460a93.json +0 -1
- /xinference/ui/web/ui/build/static/js/{main.d192c4f3.js.LICENSE.txt → main.45e78536.js.LICENSE.txt} +0 -0
- {xinference-1.10.1.dist-info → xinference-1.11.0.dist-info}/WHEEL +0 -0
- {xinference-1.10.1.dist-info → xinference-1.11.0.dist-info}/entry_points.txt +0 -0
- {xinference-1.10.1.dist-info → xinference-1.11.0.dist-info}/licenses/LICENSE +0 -0
- {xinference-1.10.1.dist-info → xinference-1.11.0.dist-info}/top_level.txt +0 -0
|
@@ -74,6 +74,7 @@ class AsyncRESTfulModelHandle:
|
|
|
74
74
|
self._model_uid = model_uid
|
|
75
75
|
self._base_url = base_url
|
|
76
76
|
self.auth_headers = auth_headers
|
|
77
|
+
self.timeout = aiohttp.ClientTimeout(total=1800)
|
|
77
78
|
self.session = aiohttp.ClientSession(
|
|
78
79
|
connector=aiohttp.TCPConnector(force_close=True)
|
|
79
80
|
)
|
|
@@ -356,7 +357,7 @@ class AsyncRESTfulImageModelHandle(AsyncRESTfulModelHandle):
|
|
|
356
357
|
else:
|
|
357
358
|
# Single image
|
|
358
359
|
files.append(("image", ("image", image, "application/octet-stream")))
|
|
359
|
-
response = await self.session.post(url,
|
|
360
|
+
response = await self.session.post(url, data=files, headers=self.auth_headers)
|
|
360
361
|
if response.status != 200:
|
|
361
362
|
raise RuntimeError(
|
|
362
363
|
f"Failed to variants the images, detail: {await _get_error_string(response)}"
|
|
@@ -366,6 +367,157 @@ class AsyncRESTfulImageModelHandle(AsyncRESTfulModelHandle):
|
|
|
366
367
|
await _release_response(response)
|
|
367
368
|
return response_data
|
|
368
369
|
|
|
370
|
+
async def image_edit(
|
|
371
|
+
self,
|
|
372
|
+
image: Union[Union[str, bytes], List[Union[str, bytes]]],
|
|
373
|
+
prompt: str,
|
|
374
|
+
mask: Optional[Union[str, bytes]] = None,
|
|
375
|
+
n: int = 1,
|
|
376
|
+
size: Optional[str] = None,
|
|
377
|
+
response_format: str = "url",
|
|
378
|
+
**kwargs,
|
|
379
|
+
) -> "ImageList":
|
|
380
|
+
"""
|
|
381
|
+
Edit image(s) by the input text and optional mask.
|
|
382
|
+
|
|
383
|
+
Parameters
|
|
384
|
+
----------
|
|
385
|
+
image: `Union[Union[str, bytes], List[Union[str, bytes]]]`
|
|
386
|
+
The input image(s) to edit. Can be:
|
|
387
|
+
- Single image: file path, URL, or binary image data
|
|
388
|
+
- Multiple images: list of file paths, URLs, or binary image data
|
|
389
|
+
When multiple images are provided, the first image is used as the primary image
|
|
390
|
+
and subsequent images are used as reference images for better editing results.
|
|
391
|
+
prompt: `str`
|
|
392
|
+
The prompt or prompts to guide image editing. If not defined, you need to pass `prompt_embeds`.
|
|
393
|
+
mask: `Optional[Union[str, bytes]]`, optional
|
|
394
|
+
An optional mask image. White pixels in the mask are repainted while black pixels are preserved.
|
|
395
|
+
If provided, this will trigger inpainting mode. If not provided, this will trigger image-to-image mode.
|
|
396
|
+
n: `int`, defaults to 1
|
|
397
|
+
The number of images to generate per prompt. Must be between 1 and 10.
|
|
398
|
+
size: `Optional[str]`, optional
|
|
399
|
+
The width*height in pixels of the generated image. If not specified, uses the original image size.
|
|
400
|
+
response_format: `str`, defaults to `url`
|
|
401
|
+
The format in which the generated images are returned. Must be one of url or b64_json.
|
|
402
|
+
**kwargs
|
|
403
|
+
Additional parameters to pass to the model.
|
|
404
|
+
|
|
405
|
+
Returns
|
|
406
|
+
-------
|
|
407
|
+
ImageList
|
|
408
|
+
A list of edited image objects.
|
|
409
|
+
|
|
410
|
+
Raises
|
|
411
|
+
------
|
|
412
|
+
RuntimeError
|
|
413
|
+
If the image editing request fails.
|
|
414
|
+
|
|
415
|
+
Examples
|
|
416
|
+
--------
|
|
417
|
+
# Single image editing
|
|
418
|
+
result = await model.image_edit(
|
|
419
|
+
image="path/to/image.png",
|
|
420
|
+
prompt="make this image look like a painting"
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
# Multiple image editing with reference images
|
|
424
|
+
result = await model.image_edit(
|
|
425
|
+
image=["primary_image.png", "reference1.jpg", "reference2.png"],
|
|
426
|
+
prompt="edit the main image using the style from reference images"
|
|
427
|
+
)
|
|
428
|
+
"""
|
|
429
|
+
url = f"{self._base_url}/v1/images/edits"
|
|
430
|
+
params = {
|
|
431
|
+
"model": self._model_uid,
|
|
432
|
+
"prompt": prompt,
|
|
433
|
+
"n": n,
|
|
434
|
+
"size": size,
|
|
435
|
+
"response_format": response_format,
|
|
436
|
+
"kwargs": json.dumps(kwargs),
|
|
437
|
+
}
|
|
438
|
+
params = _filter_params(params)
|
|
439
|
+
files: List[Any] = []
|
|
440
|
+
for key, value in params.items():
|
|
441
|
+
files.append((key, (None, value)))
|
|
442
|
+
|
|
443
|
+
# Handle single image or multiple images
|
|
444
|
+
import aiohttp
|
|
445
|
+
|
|
446
|
+
data = aiohttp.FormData()
|
|
447
|
+
|
|
448
|
+
# Add all parameters as form fields
|
|
449
|
+
for key, value in params.items():
|
|
450
|
+
if value is not None:
|
|
451
|
+
data.add_field(key, str(value))
|
|
452
|
+
|
|
453
|
+
# Handle single image or multiple images
|
|
454
|
+
if isinstance(image, list):
|
|
455
|
+
# Validate image list is not empty
|
|
456
|
+
if len(image) == 0:
|
|
457
|
+
raise ValueError("Image list cannot be empty")
|
|
458
|
+
# Multiple images - send as image[] array
|
|
459
|
+
for i, img in enumerate(image):
|
|
460
|
+
if isinstance(img, str):
|
|
461
|
+
# File path - read file content
|
|
462
|
+
with open(img, "rb") as f:
|
|
463
|
+
content = f.read()
|
|
464
|
+
data.add_field(
|
|
465
|
+
f"image[]",
|
|
466
|
+
content,
|
|
467
|
+
filename=f"image_{i}.png",
|
|
468
|
+
content_type="image/png",
|
|
469
|
+
)
|
|
470
|
+
else:
|
|
471
|
+
# Binary data
|
|
472
|
+
data.add_field(
|
|
473
|
+
f"image[]",
|
|
474
|
+
img,
|
|
475
|
+
filename=f"image_{i}.png",
|
|
476
|
+
content_type="image/png",
|
|
477
|
+
)
|
|
478
|
+
else:
|
|
479
|
+
# Single image
|
|
480
|
+
if isinstance(image, str):
|
|
481
|
+
# File path - read file content
|
|
482
|
+
with open(image, "rb") as f:
|
|
483
|
+
content = f.read()
|
|
484
|
+
data.add_field(
|
|
485
|
+
"image", content, filename="image.png", content_type="image/png"
|
|
486
|
+
)
|
|
487
|
+
else:
|
|
488
|
+
# Binary data
|
|
489
|
+
data.add_field(
|
|
490
|
+
"image", image, filename="image.png", content_type="image/png"
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
if mask is not None:
|
|
494
|
+
if isinstance(mask, str):
|
|
495
|
+
# File path - read file content
|
|
496
|
+
with open(mask, "rb") as f:
|
|
497
|
+
content = f.read()
|
|
498
|
+
data.add_field(
|
|
499
|
+
"mask", content, filename="mask.png", content_type="image/png"
|
|
500
|
+
)
|
|
501
|
+
else:
|
|
502
|
+
# Binary data
|
|
503
|
+
data.add_field(
|
|
504
|
+
"mask", mask, filename="mask.png", content_type="image/png"
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
try:
|
|
508
|
+
response = await self.session.post(
|
|
509
|
+
url, data=data, headers=self.auth_headers
|
|
510
|
+
)
|
|
511
|
+
if response.status != 200:
|
|
512
|
+
raise RuntimeError(
|
|
513
|
+
f"Failed to edit the images, detail: {await _get_error_string(response)}"
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
response_data = await response.json()
|
|
517
|
+
return response_data
|
|
518
|
+
finally:
|
|
519
|
+
await _release_response(response) if "response" in locals() else None
|
|
520
|
+
|
|
369
521
|
async def inpainting(
|
|
370
522
|
self,
|
|
371
523
|
image: Union[str, bytes],
|
|
@@ -436,7 +588,7 @@ class AsyncRESTfulImageModelHandle(AsyncRESTfulModelHandle):
|
|
|
436
588
|
("mask_image", mask_image, "application/octet-stream"),
|
|
437
589
|
)
|
|
438
590
|
)
|
|
439
|
-
response = await self.session.post(url,
|
|
591
|
+
response = await self.session.post(url, data=files, headers=self.auth_headers)
|
|
440
592
|
if response.status != 200:
|
|
441
593
|
raise RuntimeError(
|
|
442
594
|
f"Failed to inpaint the images, detail: {await _get_error_string(response)}"
|
|
@@ -457,7 +609,7 @@ class AsyncRESTfulImageModelHandle(AsyncRESTfulModelHandle):
|
|
|
457
609
|
for key, value in params.items():
|
|
458
610
|
files.append((key, (None, value)))
|
|
459
611
|
files.append(("image", ("image", image, "application/octet-stream")))
|
|
460
|
-
response = await self.session.post(url,
|
|
612
|
+
response = await self.session.post(url, data=files, headers=self.auth_headers)
|
|
461
613
|
if response.status != 200:
|
|
462
614
|
raise RuntimeError(
|
|
463
615
|
f"Failed to ocr the images, detail: {await _get_error_string(response)}"
|
|
@@ -547,7 +699,7 @@ class AsyncRESTfulVideoModelHandle(AsyncRESTfulModelHandle):
|
|
|
547
699
|
for key, value in params.items():
|
|
548
700
|
files.append((key, (None, value)))
|
|
549
701
|
files.append(("image", ("image", image, "application/octet-stream")))
|
|
550
|
-
response = await self.session.post(url,
|
|
702
|
+
response = await self.session.post(url, data=files, headers=self.auth_headers)
|
|
551
703
|
if response.status != 200:
|
|
552
704
|
raise RuntimeError(
|
|
553
705
|
f"Failed to create the video from image, detail: {await _get_error_string(response)}"
|
|
@@ -987,8 +1139,9 @@ class AsyncClient:
|
|
|
987
1139
|
self.base_url = base_url
|
|
988
1140
|
self._headers: Dict[str, str] = {}
|
|
989
1141
|
self._cluster_authed = False
|
|
1142
|
+
self.timeout = aiohttp.ClientTimeout(total=1800)
|
|
990
1143
|
self.session = aiohttp.ClientSession(
|
|
991
|
-
connector=aiohttp.TCPConnector(force_close=True)
|
|
1144
|
+
connector=aiohttp.TCPConnector(force_close=True), timeout=self.timeout
|
|
992
1145
|
)
|
|
993
1146
|
self._check_cluster_authenticated()
|
|
994
1147
|
if api_key is not None and self._cluster_authed:
|
|
@@ -329,6 +329,137 @@ class RESTfulImageModelHandle(RESTfulModelHandle):
|
|
|
329
329
|
response_data = response.json()
|
|
330
330
|
return response_data
|
|
331
331
|
|
|
332
|
+
def image_edit(
|
|
333
|
+
self,
|
|
334
|
+
image: Union[Union[str, bytes], List[Union[str, bytes]]],
|
|
335
|
+
prompt: str,
|
|
336
|
+
mask: Optional[Union[str, bytes]] = None,
|
|
337
|
+
n: int = 1,
|
|
338
|
+
size: Optional[str] = None,
|
|
339
|
+
response_format: str = "url",
|
|
340
|
+
**kwargs,
|
|
341
|
+
) -> "ImageList":
|
|
342
|
+
"""
|
|
343
|
+
Edit image(s) by the input text and optional mask.
|
|
344
|
+
|
|
345
|
+
Parameters
|
|
346
|
+
----------
|
|
347
|
+
image: `Union[Union[str, bytes], List[Union[str, bytes]]]`
|
|
348
|
+
The input image(s) to edit. Can be:
|
|
349
|
+
- Single image: file path, URL, or binary image data
|
|
350
|
+
- Multiple images: list of file paths, URLs, or binary image data
|
|
351
|
+
When multiple images are provided, the first image is used as the primary image
|
|
352
|
+
and subsequent images are used as reference images for better editing results.
|
|
353
|
+
prompt: `str`
|
|
354
|
+
The prompt or prompts to guide image editing. If not defined, you need to pass `prompt_embeds`.
|
|
355
|
+
mask: `Optional[Union[str, bytes]]`, optional
|
|
356
|
+
An optional mask image. White pixels in the mask are repainted while black pixels are preserved.
|
|
357
|
+
If provided, this will trigger inpainting mode. If not provided, this will trigger image-to-image mode.
|
|
358
|
+
n: `int`, defaults to 1
|
|
359
|
+
The number of images to generate per prompt. Must be between 1 and 10.
|
|
360
|
+
size: `Optional[str]`, optional
|
|
361
|
+
The width*height in pixels of the generated image. If not specified, uses the original image size.
|
|
362
|
+
response_format: `str`, defaults to `url`
|
|
363
|
+
The format in which the generated images are returned. Must be one of url or b64_json.
|
|
364
|
+
**kwargs
|
|
365
|
+
Additional parameters to pass to the model.
|
|
366
|
+
|
|
367
|
+
Returns
|
|
368
|
+
-------
|
|
369
|
+
ImageList
|
|
370
|
+
A list of edited image objects.
|
|
371
|
+
|
|
372
|
+
Raises
|
|
373
|
+
------
|
|
374
|
+
RuntimeError
|
|
375
|
+
If the image editing request fails.
|
|
376
|
+
|
|
377
|
+
Examples
|
|
378
|
+
--------
|
|
379
|
+
# Single image editing
|
|
380
|
+
result = model.image_edit(
|
|
381
|
+
image="path/to/image.png",
|
|
382
|
+
prompt="make this image look like a painting"
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
# Multiple image editing with reference images
|
|
386
|
+
result = model.image_edit(
|
|
387
|
+
image=["primary_image.png", "reference1.jpg", "reference2.png"],
|
|
388
|
+
prompt="edit the main image using the style from reference images"
|
|
389
|
+
)
|
|
390
|
+
"""
|
|
391
|
+
url = f"{self._base_url}/v1/images/edits"
|
|
392
|
+
params = {
|
|
393
|
+
"model": self._model_uid,
|
|
394
|
+
"prompt": prompt,
|
|
395
|
+
"n": n,
|
|
396
|
+
"size": size,
|
|
397
|
+
"response_format": response_format,
|
|
398
|
+
"kwargs": json.dumps(kwargs),
|
|
399
|
+
}
|
|
400
|
+
files: List[Any] = []
|
|
401
|
+
for key, value in params.items():
|
|
402
|
+
if value is not None:
|
|
403
|
+
files.append((key, (None, value)))
|
|
404
|
+
|
|
405
|
+
# Handle single image or multiple images using requests format
|
|
406
|
+
if isinstance(image, list):
|
|
407
|
+
# Validate image list is not empty
|
|
408
|
+
if len(image) == 0:
|
|
409
|
+
raise ValueError("Image list cannot be empty")
|
|
410
|
+
# Multiple images - send as image[] array
|
|
411
|
+
for i, img in enumerate(image):
|
|
412
|
+
if isinstance(img, str):
|
|
413
|
+
# File path - open file
|
|
414
|
+
f = open(img, "rb")
|
|
415
|
+
files.append(
|
|
416
|
+
(f"image[]", (f"image_{i}", f, "application/octet-stream"))
|
|
417
|
+
)
|
|
418
|
+
else:
|
|
419
|
+
# Binary data
|
|
420
|
+
files.append(
|
|
421
|
+
(f"image[]", (f"image_{i}", img, "application/octet-stream"))
|
|
422
|
+
)
|
|
423
|
+
else:
|
|
424
|
+
# Single image
|
|
425
|
+
if isinstance(image, str):
|
|
426
|
+
# File path - open file
|
|
427
|
+
f = open(image, "rb")
|
|
428
|
+
files.append(("image", ("image", f, "application/octet-stream")))
|
|
429
|
+
else:
|
|
430
|
+
# Binary data
|
|
431
|
+
files.append(("image", ("image", image, "application/octet-stream")))
|
|
432
|
+
|
|
433
|
+
if mask is not None:
|
|
434
|
+
if isinstance(mask, str):
|
|
435
|
+
# File path - open file
|
|
436
|
+
f = open(mask, "rb")
|
|
437
|
+
files.append(("mask", ("mask", f, "application/octet-stream")))
|
|
438
|
+
else:
|
|
439
|
+
# Binary data
|
|
440
|
+
files.append(("mask", ("mask", mask, "application/octet-stream")))
|
|
441
|
+
|
|
442
|
+
try:
|
|
443
|
+
response = self.session.post(url, files=files, headers=self.auth_headers)
|
|
444
|
+
if response.status_code != 200:
|
|
445
|
+
raise RuntimeError(
|
|
446
|
+
f"Failed to edit the images, detail: {_get_error_string(response)}"
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
response_data = response.json()
|
|
450
|
+
return response_data
|
|
451
|
+
finally:
|
|
452
|
+
# Close all opened files
|
|
453
|
+
for file_item in files:
|
|
454
|
+
if (
|
|
455
|
+
len(file_item) >= 2
|
|
456
|
+
and hasattr(file_item[1], "__len__")
|
|
457
|
+
and len(file_item[1]) >= 2
|
|
458
|
+
):
|
|
459
|
+
file_obj = file_item[1][1]
|
|
460
|
+
if hasattr(file_obj, "close"):
|
|
461
|
+
file_obj.close()
|
|
462
|
+
|
|
332
463
|
def inpainting(
|
|
333
464
|
self,
|
|
334
465
|
image: Union[str, bytes],
|
xinference/core/supervisor.py
CHANGED
|
@@ -1661,6 +1661,9 @@ class SupervisorActor(xo.StatelessActor):
|
|
|
1661
1661
|
if isinstance(worker_ref, list):
|
|
1662
1662
|
# get first worker to fetch information if model across workers
|
|
1663
1663
|
worker_ref = worker_ref[0]
|
|
1664
|
+
assert not isinstance(
|
|
1665
|
+
worker_ref, (list, tuple)
|
|
1666
|
+
), "worker_ref must be a single worker"
|
|
1664
1667
|
return await worker_ref.get_model(model_uid=replica_model_uid)
|
|
1665
1668
|
|
|
1666
1669
|
@log_async(logger=logger)
|
|
@@ -1673,6 +1676,9 @@ class SupervisorActor(xo.StatelessActor):
|
|
|
1673
1676
|
if isinstance(worker_ref, list):
|
|
1674
1677
|
# get status from first shard if model has multiple shards across workers
|
|
1675
1678
|
worker_ref = worker_ref[0]
|
|
1679
|
+
assert not isinstance(
|
|
1680
|
+
worker_ref, (list, tuple)
|
|
1681
|
+
), "worker_ref must be a single worker"
|
|
1676
1682
|
return await worker_ref.get_model_status(replica_model_uid)
|
|
1677
1683
|
|
|
1678
1684
|
@log_async(logger=logger)
|
|
@@ -1691,6 +1697,9 @@ class SupervisorActor(xo.StatelessActor):
|
|
|
1691
1697
|
if isinstance(worker_ref, list):
|
|
1692
1698
|
# get status from first shard if model has multiple shards across workers
|
|
1693
1699
|
worker_ref = worker_ref[0]
|
|
1700
|
+
assert not isinstance(
|
|
1701
|
+
worker_ref, (list, tuple)
|
|
1702
|
+
), "worker_ref must be a single worker"
|
|
1694
1703
|
info = await worker_ref.describe_model(model_uid=replica_model_uid)
|
|
1695
1704
|
info["replica"] = replica_info.replica
|
|
1696
1705
|
return info
|
|
@@ -1766,6 +1775,9 @@ class SupervisorActor(xo.StatelessActor):
|
|
|
1766
1775
|
if isinstance(worker_ref, list):
|
|
1767
1776
|
# get status from first shard if model has multiple shards across workers
|
|
1768
1777
|
worker_ref = worker_ref[0]
|
|
1778
|
+
assert not isinstance(
|
|
1779
|
+
worker_ref, (list, tuple)
|
|
1780
|
+
), "worker_ref must be a single worker"
|
|
1769
1781
|
model_ref = await worker_ref.get_model(model_uid=rep_mid)
|
|
1770
1782
|
result_info = await model_ref.abort_request(request_id, block_duration)
|
|
1771
1783
|
res["msg"] = result_info
|
|
@@ -862,26 +862,6 @@
|
|
|
862
862
|
"model_revision": "master"
|
|
863
863
|
}
|
|
864
864
|
}
|
|
865
|
-
},
|
|
866
|
-
{
|
|
867
|
-
"version": 2,
|
|
868
|
-
"model_name": "Kokoro-82M-v1.1-zh",
|
|
869
|
-
"model_family": "Kokoro-zh",
|
|
870
|
-
"model_ability": [
|
|
871
|
-
"text2audio",
|
|
872
|
-
"text2audio_zero_shot"
|
|
873
|
-
],
|
|
874
|
-
"multilingual": false,
|
|
875
|
-
"model_src": {
|
|
876
|
-
"huggingface": {
|
|
877
|
-
"model_id": "hexgrad/Kokoro-82M-v1.1-zh",
|
|
878
|
-
"model_revision": "01e7505bd6a7a2ac4975463114c3a7650a9f7218"
|
|
879
|
-
},
|
|
880
|
-
"modelscope": {
|
|
881
|
-
"model_id": "AI-ModelScope/Kokoro-82M-v1.1-zh",
|
|
882
|
-
"model_revision": "master"
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
865
|
},
|
|
886
866
|
{
|
|
887
867
|
"version": 2,
|
|
@@ -932,6 +912,26 @@
|
|
|
932
912
|
}
|
|
933
913
|
}
|
|
934
914
|
},
|
|
915
|
+
{
|
|
916
|
+
"version": 2,
|
|
917
|
+
"model_name": "Kokoro-82M-v1.1-zh",
|
|
918
|
+
"model_family": "Kokoro-zh",
|
|
919
|
+
"model_ability": [
|
|
920
|
+
"text2audio",
|
|
921
|
+
"text2audio_zero_shot"
|
|
922
|
+
],
|
|
923
|
+
"multilingual": false,
|
|
924
|
+
"model_src": {
|
|
925
|
+
"huggingface": {
|
|
926
|
+
"model_id": "hexgrad/Kokoro-82M-v1.1-zh",
|
|
927
|
+
"model_revision": "01e7505bd6a7a2ac4975463114c3a7650a9f7218"
|
|
928
|
+
},
|
|
929
|
+
"modelscope": {
|
|
930
|
+
"model_id": "AI-ModelScope/Kokoro-82M-v1.1-zh",
|
|
931
|
+
"model_revision": "master"
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
},
|
|
935
935
|
{
|
|
936
936
|
"version": 2,
|
|
937
937
|
"model_name": "IndexTTS2",
|