xinference 0.15.0__py3-none-any.whl → 0.15.1__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 +204 -1
- xinference/client/restful/restful_client.py +4 -2
- xinference/core/image_interface.py +28 -0
- xinference/core/model.py +28 -0
- xinference/core/supervisor.py +6 -0
- xinference/model/audio/fish_speech.py +9 -9
- xinference/model/audio/model_spec.json +9 -9
- xinference/model/audio/whisper.py +4 -1
- xinference/model/image/core.py +2 -1
- xinference/model/image/model_spec.json +16 -4
- xinference/model/image/model_spec_modelscope.json +16 -4
- xinference/model/image/sdapi.py +136 -0
- xinference/model/image/stable_diffusion/core.py +148 -20
- xinference/model/llm/__init__.py +8 -0
- xinference/model/llm/llm_family.json +393 -0
- xinference/model/llm/llm_family.py +3 -1
- xinference/model/llm/llm_family_modelscope.json +408 -3
- xinference/model/llm/sglang/core.py +3 -0
- xinference/model/llm/transformers/chatglm.py +1 -1
- xinference/model/llm/transformers/core.py +6 -0
- xinference/model/llm/transformers/deepseek_v2.py +340 -0
- xinference/model/llm/transformers/qwen2_audio.py +168 -0
- xinference/model/llm/transformers/qwen2_vl.py +31 -5
- xinference/model/llm/utils.py +104 -84
- xinference/model/llm/vllm/core.py +8 -0
- xinference/thirdparty/fish_speech/fish_speech/configs/firefly_gan_vq.yaml +2 -3
- xinference/thirdparty/fish_speech/fish_speech/configs/text2semantic_finetune.yaml +1 -1
- xinference/thirdparty/fish_speech/fish_speech/i18n/locale/en_US.json +1 -1
- xinference/thirdparty/fish_speech/fish_speech/i18n/locale/es_ES.json +1 -1
- xinference/thirdparty/fish_speech/fish_speech/i18n/locale/ja_JP.json +1 -1
- xinference/thirdparty/fish_speech/fish_speech/i18n/locale/pt_BR.json +1 -1
- xinference/thirdparty/fish_speech/fish_speech/i18n/locale/zh_CN.json +1 -1
- xinference/thirdparty/fish_speech/fish_speech/models/text2semantic/llama.py +2 -2
- xinference/thirdparty/fish_speech/fish_speech/models/vqgan/__init__.py +0 -3
- xinference/thirdparty/fish_speech/fish_speech/models/vqgan/modules/firefly.py +169 -198
- xinference/thirdparty/fish_speech/fish_speech/models/vqgan/modules/fsq.py +4 -27
- xinference/thirdparty/fish_speech/fish_speech/text/clean.py +9 -47
- xinference/thirdparty/fish_speech/fish_speech/text/spliter.py +2 -2
- xinference/thirdparty/fish_speech/fish_speech/train.py +2 -0
- xinference/thirdparty/fish_speech/fish_speech/webui/manage.py +12 -10
- xinference/thirdparty/fish_speech/tools/api.py +79 -134
- xinference/thirdparty/fish_speech/tools/commons.py +35 -0
- xinference/thirdparty/fish_speech/tools/download_models.py +3 -3
- xinference/thirdparty/fish_speech/tools/file.py +17 -0
- xinference/thirdparty/fish_speech/tools/llama/build_dataset.py +1 -1
- xinference/thirdparty/fish_speech/tools/llama/generate.py +29 -24
- xinference/thirdparty/fish_speech/tools/llama/merge_lora.py +1 -1
- xinference/thirdparty/fish_speech/tools/llama/quantize.py +2 -2
- xinference/thirdparty/fish_speech/tools/msgpack_api.py +34 -0
- xinference/thirdparty/fish_speech/tools/post_api.py +85 -44
- xinference/thirdparty/fish_speech/tools/sensevoice/fun_asr.py +1 -1
- xinference/thirdparty/fish_speech/tools/smart_pad.py +16 -3
- xinference/thirdparty/fish_speech/tools/vqgan/extract_vq.py +2 -2
- xinference/thirdparty/fish_speech/tools/vqgan/inference.py +4 -2
- xinference/thirdparty/fish_speech/tools/webui.py +12 -146
- xinference/types.py +7 -4
- xinference/web/ui/build/asset-manifest.json +6 -6
- xinference/web/ui/build/index.html +1 -1
- xinference/web/ui/build/static/css/{main.632e9148.css → main.5061c4c3.css} +2 -2
- xinference/web/ui/build/static/css/main.5061c4c3.css.map +1 -0
- xinference/web/ui/build/static/js/{main.9cfafbd6.js → main.754740c0.js} +3 -3
- xinference/web/ui/build/static/js/main.754740c0.js.map +1 -0
- xinference/web/ui/node_modules/.cache/babel-loader/cd90b08d177025dfe84209596fc51878f8a86bcaa6a240848a3d2e5fd4c7ff24.json +1 -0
- xinference/web/ui/node_modules/.cache/babel-loader/e42b72d4cc1ea412ebecbb8d040dc6c6bfee462c33903c2f1f3facb602ad742e.json +1 -0
- {xinference-0.15.0.dist-info → xinference-0.15.1.dist-info}/METADATA +9 -3
- {xinference-0.15.0.dist-info → xinference-0.15.1.dist-info}/RECORD +72 -74
- xinference/thirdparty/fish_speech/fish_speech/models/vqgan/lit_module.py +0 -442
- xinference/thirdparty/fish_speech/fish_speech/models/vqgan/modules/discriminator.py +0 -44
- xinference/thirdparty/fish_speech/fish_speech/models/vqgan/modules/reference.py +0 -115
- xinference/thirdparty/fish_speech/fish_speech/models/vqgan/modules/wavenet.py +0 -225
- xinference/thirdparty/fish_speech/tools/auto_rerank.py +0 -159
- xinference/thirdparty/fish_speech/tools/gen_ref.py +0 -36
- xinference/thirdparty/fish_speech/tools/merge_asr_files.py +0 -55
- xinference/web/ui/build/static/css/main.632e9148.css.map +0 -1
- xinference/web/ui/build/static/js/main.9cfafbd6.js.map +0 -1
- xinference/web/ui/node_modules/.cache/babel-loader/01d6d198156bacbd436c51435edbd4b2cacd47a79db929105eba30f74b67d48d.json +0 -1
- xinference/web/ui/node_modules/.cache/babel-loader/59eb25f514afcc4fefd1b309d192b2455f1e0aec68a9de598ca4b2333fe2c774.json +0 -1
- /xinference/web/ui/build/static/js/{main.9cfafbd6.js.LICENSE.txt → main.754740c0.js.LICENSE.txt} +0 -0
- {xinference-0.15.0.dist-info → xinference-0.15.1.dist-info}/LICENSE +0 -0
- {xinference-0.15.0.dist-info → xinference-0.15.1.dist-info}/WHEEL +0 -0
- {xinference-0.15.0.dist-info → xinference-0.15.1.dist-info}/entry_points.txt +0 -0
- {xinference-0.15.0.dist-info → xinference-0.15.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Copyright 2022-2023 XProbe Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
import base64
|
|
15
|
+
import io
|
|
16
|
+
import warnings
|
|
17
|
+
|
|
18
|
+
from PIL import Image
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SDAPIToDiffusersConverter:
|
|
22
|
+
txt2img_identical_args = {
|
|
23
|
+
"prompt",
|
|
24
|
+
"negative_prompt",
|
|
25
|
+
"seed",
|
|
26
|
+
"width",
|
|
27
|
+
"height",
|
|
28
|
+
"sampler_name",
|
|
29
|
+
}
|
|
30
|
+
txt2img_arg_mapping = {
|
|
31
|
+
"steps": "num_inference_steps",
|
|
32
|
+
"cfg_scale": "guidance_scale",
|
|
33
|
+
# "denoising_strength": "strength",
|
|
34
|
+
}
|
|
35
|
+
img2img_identical_args = {
|
|
36
|
+
"prompt",
|
|
37
|
+
"negative_prompt",
|
|
38
|
+
"seed",
|
|
39
|
+
"width",
|
|
40
|
+
"height",
|
|
41
|
+
"sampler_name",
|
|
42
|
+
}
|
|
43
|
+
img2img_arg_mapping = {
|
|
44
|
+
"init_images": "image",
|
|
45
|
+
"steps": "num_inference_steps",
|
|
46
|
+
"cfg_scale": "guidance_scale",
|
|
47
|
+
"denoising_strength": "strength",
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def convert_to_diffusers(sd_type: str, params: dict) -> dict:
|
|
52
|
+
diffusers_params = {}
|
|
53
|
+
|
|
54
|
+
identical_args = getattr(SDAPIToDiffusersConverter, f"{sd_type}_identical_args")
|
|
55
|
+
mapping_args = getattr(SDAPIToDiffusersConverter, f"{sd_type}_arg_mapping")
|
|
56
|
+
for param, value in params.items():
|
|
57
|
+
if param in identical_args:
|
|
58
|
+
diffusers_params[param] = value
|
|
59
|
+
elif param in mapping_args:
|
|
60
|
+
diffusers_params[mapping_args[param]] = value
|
|
61
|
+
else:
|
|
62
|
+
raise ValueError(f"Unknown arg: {param}")
|
|
63
|
+
|
|
64
|
+
return diffusers_params
|
|
65
|
+
|
|
66
|
+
@staticmethod
|
|
67
|
+
def get_available_args(sd_type: str) -> set:
|
|
68
|
+
identical_args = getattr(SDAPIToDiffusersConverter, f"{sd_type}_identical_args")
|
|
69
|
+
mapping_args = getattr(SDAPIToDiffusersConverter, f"{sd_type}_arg_mapping")
|
|
70
|
+
return identical_args.union(mapping_args)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class SDAPIDiffusionModelMixin:
|
|
74
|
+
@staticmethod
|
|
75
|
+
def _check_kwargs(sd_type: str, kwargs: dict):
|
|
76
|
+
available_args = SDAPIToDiffusersConverter.get_available_args(sd_type)
|
|
77
|
+
unknown_args = []
|
|
78
|
+
available_kwargs = {}
|
|
79
|
+
for arg, value in kwargs.items():
|
|
80
|
+
if arg in available_args:
|
|
81
|
+
available_kwargs[arg] = value
|
|
82
|
+
else:
|
|
83
|
+
unknown_args.append(arg)
|
|
84
|
+
if unknown_args:
|
|
85
|
+
warnings.warn(
|
|
86
|
+
f"Some args are not supported for now and will be ignored: {unknown_args}"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
converted_kwargs = SDAPIToDiffusersConverter.convert_to_diffusers(
|
|
90
|
+
sd_type, available_kwargs
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
width, height = converted_kwargs.pop("width", None), converted_kwargs.pop(
|
|
94
|
+
"height", None
|
|
95
|
+
)
|
|
96
|
+
if width and height:
|
|
97
|
+
converted_kwargs["size"] = f"{width}*{height}"
|
|
98
|
+
|
|
99
|
+
return converted_kwargs
|
|
100
|
+
|
|
101
|
+
def txt2img(self, **kwargs):
|
|
102
|
+
converted_kwargs = self._check_kwargs("txt2img", kwargs)
|
|
103
|
+
result = self.text_to_image(response_format="b64_json", **converted_kwargs) # type: ignore
|
|
104
|
+
|
|
105
|
+
# convert to SD API result
|
|
106
|
+
return {
|
|
107
|
+
"images": [r["b64_json"] for r in result["data"]],
|
|
108
|
+
"info": {"created": result["created"]},
|
|
109
|
+
"parameters": {},
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@staticmethod
|
|
113
|
+
def _decode_b64_img(img_str: str) -> Image:
|
|
114
|
+
# img_str in a format: "data:image/png;base64," + raw_b64_img(image)
|
|
115
|
+
f, data = img_str.split(",", 1)
|
|
116
|
+
f, encode_type = f.split(";", 1)
|
|
117
|
+
assert encode_type == "base64"
|
|
118
|
+
f = f.split("/", 1)[1]
|
|
119
|
+
b = base64.b64decode(data)
|
|
120
|
+
return Image.open(io.BytesIO(b), formats=[f])
|
|
121
|
+
|
|
122
|
+
def img2img(self, **kwargs):
|
|
123
|
+
init_images = kwargs.pop("init_images", [])
|
|
124
|
+
kwargs["init_images"] = [self._decode_b64_img(i) for i in init_images]
|
|
125
|
+
clip_skip = kwargs.get("override_settings", {}).get("clip_skip")
|
|
126
|
+
converted_kwargs = self._check_kwargs("img2img", kwargs)
|
|
127
|
+
if clip_skip:
|
|
128
|
+
converted_kwargs["clip_skip"] = clip_skip
|
|
129
|
+
result = self.image_to_image(response_format="b64_json", **converted_kwargs) # type: ignore
|
|
130
|
+
|
|
131
|
+
# convert to SD API result
|
|
132
|
+
return {
|
|
133
|
+
"images": [r["b64_json"] for r in result["data"]],
|
|
134
|
+
"info": {"created": result["created"]},
|
|
135
|
+
"parameters": {},
|
|
136
|
+
}
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
import base64
|
|
16
|
+
import contextlib
|
|
17
|
+
import inspect
|
|
16
18
|
import logging
|
|
17
19
|
import os
|
|
18
20
|
import re
|
|
@@ -22,19 +24,43 @@ import uuid
|
|
|
22
24
|
from concurrent.futures import ThreadPoolExecutor
|
|
23
25
|
from functools import partial
|
|
24
26
|
from io import BytesIO
|
|
25
|
-
from typing import Dict, List, Optional, Union
|
|
27
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
|
26
28
|
|
|
27
29
|
import PIL.Image
|
|
30
|
+
import torch
|
|
28
31
|
from PIL import ImageOps
|
|
29
32
|
|
|
30
33
|
from ....constants import XINFERENCE_IMAGE_DIR
|
|
31
34
|
from ....device_utils import move_model_to_available_device
|
|
32
35
|
from ....types import Image, ImageList, LoRA
|
|
36
|
+
from ..sdapi import SDAPIDiffusionModelMixin
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
if TYPE_CHECKING:
|
|
39
|
+
from ..core import ImageModelFamilyV1
|
|
35
40
|
|
|
41
|
+
logger = logging.getLogger(__name__)
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
SAMPLING_METHODS = [
|
|
44
|
+
"default",
|
|
45
|
+
"DPM++ 2M",
|
|
46
|
+
"DPM++ 2M Karras",
|
|
47
|
+
"DPM++ 2M SDE",
|
|
48
|
+
"DPM++ 2M SDE Karras",
|
|
49
|
+
"DPM++ SDE",
|
|
50
|
+
"DPM++ SDE Karras",
|
|
51
|
+
"DPM2",
|
|
52
|
+
"DPM2 Karras",
|
|
53
|
+
"DPM2 a",
|
|
54
|
+
"DPM2 a Karras",
|
|
55
|
+
"Euler",
|
|
56
|
+
"Euler a",
|
|
57
|
+
"Heun",
|
|
58
|
+
"LMS",
|
|
59
|
+
"LMS Karras",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class DiffusionModel(SDAPIDiffusionModelMixin):
|
|
38
64
|
def __init__(
|
|
39
65
|
self,
|
|
40
66
|
model_uid: str,
|
|
@@ -43,7 +69,7 @@ class DiffusionModel:
|
|
|
43
69
|
lora_model: Optional[List[LoRA]] = None,
|
|
44
70
|
lora_load_kwargs: Optional[Dict] = None,
|
|
45
71
|
lora_fuse_kwargs: Optional[Dict] = None,
|
|
46
|
-
|
|
72
|
+
model_spec: Optional["ImageModelFamilyV1"] = None,
|
|
47
73
|
**kwargs,
|
|
48
74
|
):
|
|
49
75
|
self._model_uid = model_uid
|
|
@@ -59,7 +85,8 @@ class DiffusionModel:
|
|
|
59
85
|
self._lora_model = lora_model
|
|
60
86
|
self._lora_load_kwargs = lora_load_kwargs or {}
|
|
61
87
|
self._lora_fuse_kwargs = lora_fuse_kwargs or {}
|
|
62
|
-
self.
|
|
88
|
+
self._model_spec = model_spec
|
|
89
|
+
self._abilities = model_spec.model_ability or [] # type: ignore
|
|
63
90
|
self._kwargs = kwargs
|
|
64
91
|
|
|
65
92
|
@property
|
|
@@ -80,8 +107,6 @@ class DiffusionModel:
|
|
|
80
107
|
logger.info(f"Successfully loaded the LoRA for model {self._model_uid}.")
|
|
81
108
|
|
|
82
109
|
def load(self):
|
|
83
|
-
import torch
|
|
84
|
-
|
|
85
110
|
if "text2image" in self._abilities or "image2image" in self._abilities:
|
|
86
111
|
from diffusers import AutoPipelineForText2Image as AutoPipelineModel
|
|
87
112
|
elif "inpainting" in self._abilities:
|
|
@@ -143,7 +168,9 @@ class DiffusionModel:
|
|
|
143
168
|
self._kwargs[text_encoder_name] = text_encoder
|
|
144
169
|
self._kwargs["device_map"] = "balanced"
|
|
145
170
|
|
|
146
|
-
logger.debug(
|
|
171
|
+
logger.debug(
|
|
172
|
+
"Loading model from %s, kwargs: %s", self._model_path, self._kwargs
|
|
173
|
+
)
|
|
147
174
|
self._model = AutoPipelineModel.from_pretrained(
|
|
148
175
|
self._model_path,
|
|
149
176
|
**self._kwargs,
|
|
@@ -158,6 +185,89 @@ class DiffusionModel:
|
|
|
158
185
|
self._model.enable_attention_slicing()
|
|
159
186
|
self._apply_lora()
|
|
160
187
|
|
|
188
|
+
@staticmethod
|
|
189
|
+
def _get_scheduler(model: Any, sampler_name: str):
|
|
190
|
+
if not sampler_name:
|
|
191
|
+
return
|
|
192
|
+
|
|
193
|
+
assert model is not None
|
|
194
|
+
|
|
195
|
+
import diffusers
|
|
196
|
+
|
|
197
|
+
# see https://github.com/huggingface/diffusers/issues/4167
|
|
198
|
+
# to get A1111 <> Diffusers Scheduler mapping
|
|
199
|
+
if sampler_name == "DPM++ 2M":
|
|
200
|
+
return diffusers.DPMSolverMultistepScheduler.from_config(
|
|
201
|
+
model.scheduler.config
|
|
202
|
+
)
|
|
203
|
+
elif sampler_name == "DPM++ 2M Karras":
|
|
204
|
+
return diffusers.DPMSolverMultistepScheduler.from_config(
|
|
205
|
+
model.scheduler.config, use_karras_sigmas=True
|
|
206
|
+
)
|
|
207
|
+
elif sampler_name == "DPM++ 2M SDE":
|
|
208
|
+
return diffusers.DPMSolverMultistepScheduler.from_config(
|
|
209
|
+
model.scheduler.config, algorithm_type="sde-dpmsolver++"
|
|
210
|
+
)
|
|
211
|
+
elif sampler_name == "DPM++ 2M SDE Karras":
|
|
212
|
+
return diffusers.DPMSolverMultistepScheduler.from_config(
|
|
213
|
+
model.scheduler.config,
|
|
214
|
+
algorithm_type="sde-dpmsolver++",
|
|
215
|
+
use_karras_sigmas=True,
|
|
216
|
+
)
|
|
217
|
+
elif sampler_name == "DPM++ SDE":
|
|
218
|
+
return diffusers.DPMSolverSinglestepScheduler.from_config(
|
|
219
|
+
model.scheduler.config
|
|
220
|
+
)
|
|
221
|
+
elif sampler_name == "DPM++ SDE Karras":
|
|
222
|
+
return diffusers.DPMSolverSinglestepScheduler.from_config(
|
|
223
|
+
model.scheduler.config, use_karras_sigmas=True
|
|
224
|
+
)
|
|
225
|
+
elif sampler_name == "DPM2":
|
|
226
|
+
return diffusers.KDPM2DiscreteScheduler.from_config(model.scheduler.config)
|
|
227
|
+
elif sampler_name == "DPM2 Karras":
|
|
228
|
+
return diffusers.KDPM2DiscreteScheduler.from_config(
|
|
229
|
+
model.scheduler.config, use_karras_sigmas=True
|
|
230
|
+
)
|
|
231
|
+
elif sampler_name == "DPM2 a":
|
|
232
|
+
return diffusers.KDPM2AncestralDiscreteScheduler.from_config(
|
|
233
|
+
model.scheduler.config
|
|
234
|
+
)
|
|
235
|
+
elif sampler_name == "DPM2 a Karras":
|
|
236
|
+
return diffusers.KDPM2AncestralDiscreteScheduler.from_config(
|
|
237
|
+
model.scheduler.config, use_karras_sigmas=True
|
|
238
|
+
)
|
|
239
|
+
elif sampler_name == "Euler":
|
|
240
|
+
return diffusers.EulerDiscreteScheduler.from_config(model.scheduler.config)
|
|
241
|
+
elif sampler_name == "Euler a":
|
|
242
|
+
return diffusers.EulerAncestralDiscreteScheduler.from_config(
|
|
243
|
+
model.scheduler.config
|
|
244
|
+
)
|
|
245
|
+
elif sampler_name == "Heun":
|
|
246
|
+
return diffusers.HeunDiscreteScheduler.from_config(model.scheduler.config)
|
|
247
|
+
elif sampler_name == "LMS":
|
|
248
|
+
return diffusers.LMSDiscreteScheduler.from_config(model.scheduler.config)
|
|
249
|
+
elif sampler_name == "LMS Karras":
|
|
250
|
+
return diffusers.LMSDiscreteScheduler.from_config(
|
|
251
|
+
model.scheduler.config, use_karras_sigmas=True
|
|
252
|
+
)
|
|
253
|
+
else:
|
|
254
|
+
raise ValueError(f"Unknown sampler: {sampler_name}")
|
|
255
|
+
|
|
256
|
+
@staticmethod
|
|
257
|
+
@contextlib.contextmanager
|
|
258
|
+
def _reset_when_done(model: Any, sampler_name: str):
|
|
259
|
+
assert model is not None
|
|
260
|
+
scheduler = DiffusionModel._get_scheduler(model, sampler_name)
|
|
261
|
+
if scheduler:
|
|
262
|
+
default_scheduler = model.scheduler
|
|
263
|
+
model.scheduler = scheduler
|
|
264
|
+
try:
|
|
265
|
+
yield
|
|
266
|
+
finally:
|
|
267
|
+
model.scheduler = default_scheduler
|
|
268
|
+
else:
|
|
269
|
+
yield
|
|
270
|
+
|
|
161
271
|
def _call_model(
|
|
162
272
|
self,
|
|
163
273
|
response_format: str,
|
|
@@ -168,16 +278,19 @@ class DiffusionModel:
|
|
|
168
278
|
|
|
169
279
|
from ....device_utils import empty_cache
|
|
170
280
|
|
|
171
|
-
|
|
172
|
-
"stable diffusion args: %s",
|
|
173
|
-
kwargs,
|
|
174
|
-
)
|
|
281
|
+
model = model if model is not None else self._model
|
|
175
282
|
is_padded = kwargs.pop("is_padded", None)
|
|
176
283
|
origin_size = kwargs.pop("origin_size", None)
|
|
177
|
-
|
|
178
|
-
|
|
284
|
+
seed = kwargs.pop("seed", None)
|
|
285
|
+
if seed is not None:
|
|
286
|
+
kwargs["generator"] = generator = torch.Generator(device=self._model.device) # type: ignore
|
|
287
|
+
if seed != -1:
|
|
288
|
+
kwargs["generator"] = generator.manual_seed(seed)
|
|
289
|
+
sampler_name = kwargs.pop("sampler_name", None)
|
|
179
290
|
assert callable(model)
|
|
180
|
-
|
|
291
|
+
with self._reset_when_done(model, sampler_name):
|
|
292
|
+
logger.debug("stable diffusion args: %s, model: %s", kwargs, model)
|
|
293
|
+
images = model(**kwargs).images
|
|
181
294
|
|
|
182
295
|
# revert padding if padded
|
|
183
296
|
if is_padded and origin_size:
|
|
@@ -231,14 +344,16 @@ class DiffusionModel:
|
|
|
231
344
|
# References:
|
|
232
345
|
# https://huggingface.co/docs/diffusers/main/en/api/pipelines/controlnet_sdxl
|
|
233
346
|
width, height = map(int, re.split(r"[^\d]+", size))
|
|
234
|
-
self.
|
|
347
|
+
generate_kwargs = self._model_spec.default_generate_config.copy() # type: ignore
|
|
348
|
+
generate_kwargs.update({k: v for k, v in kwargs.items() if v is not None})
|
|
349
|
+
self._filter_kwargs(generate_kwargs)
|
|
235
350
|
return self._call_model(
|
|
236
351
|
prompt=prompt,
|
|
237
352
|
height=height,
|
|
238
353
|
width=width,
|
|
239
354
|
num_images_per_prompt=n,
|
|
240
355
|
response_format=response_format,
|
|
241
|
-
**
|
|
356
|
+
**generate_kwargs,
|
|
242
357
|
)
|
|
243
358
|
|
|
244
359
|
@staticmethod
|
|
@@ -287,12 +402,24 @@ class DiffusionModel:
|
|
|
287
402
|
width, height = image.size
|
|
288
403
|
kwargs["width"] = width
|
|
289
404
|
kwargs["height"] = height
|
|
290
|
-
|
|
405
|
+
else:
|
|
406
|
+
# SD3 image2image cannot accept width and height
|
|
407
|
+
parameters = inspect.signature(model.__call__).parameters # type: ignore
|
|
408
|
+
allow_width_height = False
|
|
409
|
+
for param in parameters.values():
|
|
410
|
+
if param.kind == inspect.Parameter.VAR_KEYWORD:
|
|
411
|
+
allow_width_height = True
|
|
412
|
+
break
|
|
413
|
+
if "width" in parameters or "height" in parameters:
|
|
414
|
+
allow_width_height = True
|
|
415
|
+
if allow_width_height:
|
|
416
|
+
kwargs["width"], kwargs["height"] = image.size
|
|
417
|
+
|
|
418
|
+
kwargs["negative_prompt"] = negative_prompt
|
|
291
419
|
self._filter_kwargs(kwargs)
|
|
292
420
|
return self._call_model(
|
|
293
421
|
image=image,
|
|
294
422
|
prompt=prompt,
|
|
295
|
-
negative_prompt=negative_prompt,
|
|
296
423
|
num_images_per_prompt=n,
|
|
297
424
|
response_format=response_format,
|
|
298
425
|
model=model,
|
|
@@ -342,11 +469,12 @@ class DiffusionModel:
|
|
|
342
469
|
# calculate actual image size after padding
|
|
343
470
|
width, height = image.size
|
|
344
471
|
|
|
472
|
+
kwargs["negative_prompt"] = negative_prompt
|
|
473
|
+
self._filter_kwargs(kwargs)
|
|
345
474
|
return self._call_model(
|
|
346
475
|
image=image,
|
|
347
476
|
mask_image=mask_image,
|
|
348
477
|
prompt=prompt,
|
|
349
|
-
negative_prompt=negative_prompt,
|
|
350
478
|
height=height,
|
|
351
479
|
width=width,
|
|
352
480
|
num_images_per_prompt=n,
|
xinference/model/llm/__init__.py
CHANGED
|
@@ -136,12 +136,17 @@ def _install():
|
|
|
136
136
|
from .transformers.cogvlm2 import CogVLM2Model
|
|
137
137
|
from .transformers.cogvlm2_video import CogVLM2VideoModel
|
|
138
138
|
from .transformers.core import PytorchChatModel, PytorchModel
|
|
139
|
+
from .transformers.deepseek_v2 import (
|
|
140
|
+
DeepSeekV2PytorchChatModel,
|
|
141
|
+
DeepSeekV2PytorchModel,
|
|
142
|
+
)
|
|
139
143
|
from .transformers.deepseek_vl import DeepSeekVLChatModel
|
|
140
144
|
from .transformers.glm4v import Glm4VModel
|
|
141
145
|
from .transformers.intern_vl import InternVLChatModel
|
|
142
146
|
from .transformers.internlm2 import Internlm2PytorchChatModel
|
|
143
147
|
from .transformers.minicpmv25 import MiniCPMV25Model
|
|
144
148
|
from .transformers.minicpmv26 import MiniCPMV26Model
|
|
149
|
+
from .transformers.qwen2_audio import Qwen2AudioChatModel
|
|
145
150
|
from .transformers.qwen2_vl import Qwen2VLChatModel
|
|
146
151
|
from .transformers.qwen_vl import QwenVLChatModel
|
|
147
152
|
from .transformers.yi_vl import YiVLChatModel
|
|
@@ -173,6 +178,7 @@ def _install():
|
|
|
173
178
|
Internlm2PytorchChatModel,
|
|
174
179
|
QwenVLChatModel,
|
|
175
180
|
Qwen2VLChatModel,
|
|
181
|
+
Qwen2AudioChatModel,
|
|
176
182
|
YiVLChatModel,
|
|
177
183
|
DeepSeekVLChatModel,
|
|
178
184
|
InternVLChatModel,
|
|
@@ -182,6 +188,8 @@ def _install():
|
|
|
182
188
|
MiniCPMV25Model,
|
|
183
189
|
MiniCPMV26Model,
|
|
184
190
|
Glm4VModel,
|
|
191
|
+
DeepSeekV2PytorchModel,
|
|
192
|
+
DeepSeekV2PytorchChatModel,
|
|
185
193
|
]
|
|
186
194
|
)
|
|
187
195
|
if OmniLMMModel: # type: ignore
|