huggingface-hub 0.28.1__py3-none-any.whl → 0.29.0rc0__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 huggingface-hub might be problematic. Click here for more details.
- huggingface_hub/__init__.py +1 -4
- huggingface_hub/constants.py +16 -10
- huggingface_hub/file_download.py +10 -6
- huggingface_hub/hf_api.py +53 -23
- huggingface_hub/inference/_client.py +151 -84
- huggingface_hub/inference/_common.py +3 -27
- huggingface_hub/inference/_generated/_async_client.py +147 -83
- huggingface_hub/inference/_generated/types/__init__.py +1 -1
- huggingface_hub/inference/_generated/types/audio_classification.py +4 -5
- huggingface_hub/inference/_generated/types/audio_to_audio.py +3 -4
- huggingface_hub/inference/_generated/types/automatic_speech_recognition.py +7 -8
- huggingface_hub/inference/_generated/types/base.py +21 -0
- huggingface_hub/inference/_generated/types/chat_completion.py +29 -30
- huggingface_hub/inference/_generated/types/depth_estimation.py +3 -4
- huggingface_hub/inference/_generated/types/document_question_answering.py +5 -6
- huggingface_hub/inference/_generated/types/feature_extraction.py +5 -6
- huggingface_hub/inference/_generated/types/fill_mask.py +4 -5
- huggingface_hub/inference/_generated/types/image_classification.py +4 -5
- huggingface_hub/inference/_generated/types/image_segmentation.py +4 -5
- huggingface_hub/inference/_generated/types/image_to_image.py +5 -6
- huggingface_hub/inference/_generated/types/image_to_text.py +5 -6
- huggingface_hub/inference/_generated/types/object_detection.py +5 -6
- huggingface_hub/inference/_generated/types/question_answering.py +5 -6
- huggingface_hub/inference/_generated/types/sentence_similarity.py +3 -4
- huggingface_hub/inference/_generated/types/summarization.py +4 -5
- huggingface_hub/inference/_generated/types/table_question_answering.py +5 -6
- huggingface_hub/inference/_generated/types/text2text_generation.py +4 -5
- huggingface_hub/inference/_generated/types/text_classification.py +4 -5
- huggingface_hub/inference/_generated/types/text_generation.py +12 -13
- huggingface_hub/inference/_generated/types/text_to_audio.py +5 -6
- huggingface_hub/inference/_generated/types/text_to_image.py +8 -15
- huggingface_hub/inference/_generated/types/text_to_speech.py +5 -6
- huggingface_hub/inference/_generated/types/text_to_video.py +4 -5
- huggingface_hub/inference/_generated/types/token_classification.py +4 -5
- huggingface_hub/inference/_generated/types/translation.py +4 -5
- huggingface_hub/inference/_generated/types/video_classification.py +4 -5
- huggingface_hub/inference/_generated/types/visual_question_answering.py +5 -6
- huggingface_hub/inference/_generated/types/zero_shot_classification.py +4 -5
- huggingface_hub/inference/_generated/types/zero_shot_image_classification.py +4 -5
- huggingface_hub/inference/_generated/types/zero_shot_object_detection.py +5 -6
- huggingface_hub/inference/_providers/__init__.py +44 -8
- huggingface_hub/inference/_providers/_common.py +239 -0
- huggingface_hub/inference/_providers/black_forest_labs.py +66 -0
- huggingface_hub/inference/_providers/fal_ai.py +31 -100
- huggingface_hub/inference/_providers/fireworks_ai.py +6 -0
- huggingface_hub/inference/_providers/hf_inference.py +58 -142
- huggingface_hub/inference/_providers/hyperbolic.py +43 -0
- huggingface_hub/inference/_providers/nebius.py +41 -0
- huggingface_hub/inference/_providers/novita.py +26 -0
- huggingface_hub/inference/_providers/replicate.py +24 -119
- huggingface_hub/inference/_providers/sambanova.py +3 -86
- huggingface_hub/inference/_providers/together.py +36 -130
- huggingface_hub/utils/_headers.py +5 -0
- huggingface_hub/utils/_hf_folder.py +4 -32
- huggingface_hub/utils/_http.py +85 -2
- huggingface_hub/utils/_typing.py +1 -1
- huggingface_hub/utils/logging.py +6 -0
- {huggingface_hub-0.28.1.dist-info → huggingface_hub-0.29.0rc0.dist-info}/METADATA +1 -1
- {huggingface_hub-0.28.1.dist-info → huggingface_hub-0.29.0rc0.dist-info}/RECORD +63 -57
- {huggingface_hub-0.28.1.dist-info → huggingface_hub-0.29.0rc0.dist-info}/LICENSE +0 -0
- {huggingface_hub-0.28.1.dist-info → huggingface_hub-0.29.0rc0.dist-info}/WHEEL +0 -0
- {huggingface_hub-0.28.1.dist-info → huggingface_hub-0.29.0rc0.dist-info}/entry_points.txt +0 -0
- {huggingface_hub-0.28.1.dist-info → huggingface_hub-0.29.0rc0.dist-info}/top_level.txt +0 -0
|
@@ -1,114 +1,32 @@
|
|
|
1
1
|
from typing import Any, Dict, Optional, Union
|
|
2
2
|
|
|
3
|
-
from huggingface_hub import
|
|
4
|
-
from huggingface_hub.inference._common import
|
|
5
|
-
from huggingface_hub.utils import
|
|
3
|
+
from huggingface_hub.inference._common import _as_dict
|
|
4
|
+
from huggingface_hub.inference._providers._common import TaskProviderHelper, filter_none
|
|
5
|
+
from huggingface_hub.utils import get_session
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
BASE_URL = "https://api.replicate.com"
|
|
12
|
-
|
|
13
|
-
SUPPORTED_MODELS = {
|
|
14
|
-
"text-to-image": {
|
|
15
|
-
"black-forest-labs/FLUX.1-dev": "black-forest-labs/flux-dev",
|
|
16
|
-
"black-forest-labs/FLUX.1-schnell": "black-forest-labs/flux-schnell",
|
|
17
|
-
"ByteDance/Hyper-SD": "bytedance/hyper-flux-16step:382cf8959fb0f0d665b26e7e80b8d6dc3faaef1510f14ce017e8c732bb3d1eb7",
|
|
18
|
-
"ByteDance/SDXL-Lightning": "bytedance/sdxl-lightning-4step:5599ed30703defd1d160a25a63321b4dec97101d98b4674bcc56e41f62f35637",
|
|
19
|
-
"playgroundai/playground-v2.5-1024px-aesthetic": "playgroundai/playground-v2.5-1024px-aesthetic:a45f82a1382bed5c7aeb861dac7c7d191b0fdf74d8d57c4a0e6ed7d4d0bf7d24",
|
|
20
|
-
"stabilityai/stable-diffusion-3.5-large-turbo": "stability-ai/stable-diffusion-3.5-large-turbo",
|
|
21
|
-
"stabilityai/stable-diffusion-3.5-large": "stability-ai/stable-diffusion-3.5-large",
|
|
22
|
-
"stabilityai/stable-diffusion-3.5-medium": "stability-ai/stable-diffusion-3.5-medium",
|
|
23
|
-
"stabilityai/stable-diffusion-xl-base-1.0": "stability-ai/sdxl:7762fd07cf82c948538e41f63f77d685e02b063e37e496e96eefd46c929f9bdc",
|
|
24
|
-
},
|
|
25
|
-
"text-to-speech": {
|
|
26
|
-
"OuteAI/OuteTTS-0.3-500M": "jbilcke/oute-tts:39a59319327b27327fa3095149c5a746e7f2aee18c75055c3368237a6503cd26",
|
|
27
|
-
},
|
|
28
|
-
"text-to-video": {
|
|
29
|
-
"genmo/mochi-1-preview": "genmoai/mochi-1:1944af04d098ef69bed7f9d335d102e652203f268ec4aaa2d836f6217217e460",
|
|
30
|
-
},
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def _build_url(base_url: str, model: str) -> str:
|
|
35
|
-
if ":" in model:
|
|
36
|
-
return f"{base_url}/v1/predictions"
|
|
37
|
-
return f"{base_url}/v1/models/{model}/predictions"
|
|
8
|
+
_PROVIDER = "replicate"
|
|
9
|
+
_BASE_URL = "https://api.replicate.com"
|
|
38
10
|
|
|
39
11
|
|
|
40
12
|
class ReplicateTask(TaskProviderHelper):
|
|
41
13
|
def __init__(self, task: str):
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if
|
|
57
|
-
|
|
58
|
-
"You must provide an api_key to work with Replicate API or log in with `huggingface-cli login`."
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
# Route to the proxy if the api_key is a HF TOKEN
|
|
62
|
-
if api_key.startswith("hf_"):
|
|
63
|
-
base_url = constants.INFERENCE_PROXY_TEMPLATE.format(provider="replicate")
|
|
64
|
-
logger.info("Calling Replicate provider through Hugging Face proxy.")
|
|
65
|
-
else:
|
|
66
|
-
base_url = BASE_URL
|
|
67
|
-
logger.info("Calling Replicate provider directly.")
|
|
68
|
-
mapped_model = self._map_model(model)
|
|
69
|
-
url = _build_url(base_url, mapped_model)
|
|
70
|
-
|
|
71
|
-
headers = {
|
|
72
|
-
**build_hf_headers(token=api_key),
|
|
73
|
-
**headers,
|
|
74
|
-
"Prefer": "wait",
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
payload = self._prepare_payload(inputs, parameters=parameters, model=mapped_model)
|
|
78
|
-
|
|
79
|
-
return RequestParameters(
|
|
80
|
-
url=url,
|
|
81
|
-
task=self.task,
|
|
82
|
-
model=mapped_model,
|
|
83
|
-
json=payload,
|
|
84
|
-
data=None,
|
|
85
|
-
headers=headers,
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
def _map_model(self, model: Optional[str]) -> str:
|
|
89
|
-
if model is None:
|
|
90
|
-
raise ValueError("Please provide a model available on Replicate.")
|
|
91
|
-
if self.task not in SUPPORTED_MODELS:
|
|
92
|
-
raise ValueError(f"Task {self.task} not supported with Replicate.")
|
|
93
|
-
mapped_model = SUPPORTED_MODELS[self.task].get(model)
|
|
94
|
-
if mapped_model is None:
|
|
95
|
-
raise ValueError(f"Model {model} is not supported with Replicate for task {self.task}.")
|
|
96
|
-
return mapped_model
|
|
97
|
-
|
|
98
|
-
def _prepare_payload(
|
|
99
|
-
self,
|
|
100
|
-
inputs: Any,
|
|
101
|
-
parameters: Dict[str, Any],
|
|
102
|
-
model: str,
|
|
103
|
-
) -> Dict[str, Any]:
|
|
104
|
-
payload: Dict[str, Any] = {
|
|
105
|
-
"input": {
|
|
106
|
-
"prompt": inputs,
|
|
107
|
-
**{k: v for k, v in parameters.items() if v is not None},
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if ":" in model:
|
|
111
|
-
version = model.split(":", 1)[1]
|
|
14
|
+
super().__init__(provider=_PROVIDER, base_url=_BASE_URL, task=task)
|
|
15
|
+
|
|
16
|
+
def _prepare_headers(self, headers: Dict, api_key: str) -> Dict:
|
|
17
|
+
headers = super()._prepare_headers(headers, api_key)
|
|
18
|
+
headers["Prefer"] = "wait"
|
|
19
|
+
return headers
|
|
20
|
+
|
|
21
|
+
def _prepare_route(self, mapped_model: str) -> str:
|
|
22
|
+
if ":" in mapped_model:
|
|
23
|
+
return "/v1/predictions"
|
|
24
|
+
return f"/v1/models/{mapped_model}/predictions"
|
|
25
|
+
|
|
26
|
+
def _prepare_payload_as_dict(self, inputs: Any, parameters: Dict, mapped_model: str) -> Optional[Dict]:
|
|
27
|
+
payload: Dict[str, Any] = {"input": {"prompt": inputs, **filter_none(parameters)}}
|
|
28
|
+
if ":" in mapped_model:
|
|
29
|
+
version = mapped_model.split(":", 1)[1]
|
|
112
30
|
payload["version"] = version
|
|
113
31
|
return payload
|
|
114
32
|
|
|
@@ -129,20 +47,7 @@ class ReplicateTextToSpeechTask(ReplicateTask):
|
|
|
129
47
|
def __init__(self):
|
|
130
48
|
super().__init__("text-to-speech")
|
|
131
49
|
|
|
132
|
-
def
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
parameters: Dict[str, Any],
|
|
136
|
-
model: str,
|
|
137
|
-
) -> Dict[str, Any]:
|
|
138
|
-
# The following payload might work only for a subset of text-to-speech Replicate models.
|
|
139
|
-
payload: Dict[str, Any] = {
|
|
140
|
-
"input": {
|
|
141
|
-
"inputs": inputs,
|
|
142
|
-
**{k: v for k, v in parameters.items() if v is not None},
|
|
143
|
-
},
|
|
144
|
-
}
|
|
145
|
-
if ":" in model:
|
|
146
|
-
version = model.split(":", 1)[1]
|
|
147
|
-
payload["version"] = version
|
|
50
|
+
def _prepare_payload_as_dict(self, inputs: Any, parameters: Dict, mapped_model: str) -> Optional[Dict]:
|
|
51
|
+
payload: Dict = super()._prepare_payload_as_dict(inputs, parameters, mapped_model) # type: ignore[assignment]
|
|
52
|
+
payload["input"]["text"] = payload["input"].pop("prompt") # rename "prompt" to "text" for TTS
|
|
148
53
|
return payload
|
|
@@ -1,89 +1,6 @@
|
|
|
1
|
-
from
|
|
1
|
+
from huggingface_hub.inference._providers._common import BaseConversationalTask
|
|
2
2
|
|
|
3
|
-
from huggingface_hub import constants
|
|
4
|
-
from huggingface_hub.inference._common import RequestParameters, TaskProviderHelper
|
|
5
|
-
from huggingface_hub.utils import build_hf_headers, get_token, logging
|
|
6
3
|
|
|
7
|
-
|
|
8
|
-
logger = logging.get_logger(__name__)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
BASE_URL = "https://api.sambanova.ai"
|
|
12
|
-
|
|
13
|
-
SUPPORTED_MODELS = {
|
|
14
|
-
"conversational": {
|
|
15
|
-
"Qwen/Qwen2.5-Coder-32B-Instruct": "Qwen2.5-Coder-32B-Instruct",
|
|
16
|
-
"Qwen/Qwen2.5-72B-Instruct": "Qwen2.5-72B-Instruct",
|
|
17
|
-
"Qwen/QwQ-32B-Preview": "QwQ-32B-Preview",
|
|
18
|
-
"meta-llama/Llama-3.3-70B-Instruct": "Meta-Llama-3.3-70B-Instruct",
|
|
19
|
-
"meta-llama/Llama-3.2-1B": "Meta-Llama-3.2-1B-Instruct",
|
|
20
|
-
"meta-llama/Llama-3.2-3B": "Meta-Llama-3.2-3B-Instruct",
|
|
21
|
-
"meta-llama/Llama-3.2-11B-Vision-Instruct": "Llama-3.2-11B-Vision-Instruct",
|
|
22
|
-
"meta-llama/Llama-3.2-90B-Vision-Instruct": "Llama-3.2-90B-Vision-Instruct",
|
|
23
|
-
"meta-llama/Llama-3.1-8B-Instruct": "Meta-Llama-3.1-8B-Instruct",
|
|
24
|
-
"meta-llama/Llama-3.1-70B-Instruct": "Meta-Llama-3.1-70B-Instruct",
|
|
25
|
-
"meta-llama/Llama-3.1-405B-Instruct": "Meta-Llama-3.1-405B-Instruct",
|
|
26
|
-
"meta-llama/Llama-Guard-3-8B": "Meta-Llama-Guard-3-8B",
|
|
27
|
-
},
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class SambanovaConversationalTask(TaskProviderHelper):
|
|
4
|
+
class SambanovaConversationalTask(BaseConversationalTask):
|
|
32
5
|
def __init__(self):
|
|
33
|
-
|
|
34
|
-
self.task = "conversational"
|
|
35
|
-
|
|
36
|
-
def prepare_request(
|
|
37
|
-
self,
|
|
38
|
-
*,
|
|
39
|
-
inputs: Any,
|
|
40
|
-
parameters: Dict[str, Any],
|
|
41
|
-
headers: Dict,
|
|
42
|
-
model: Optional[str],
|
|
43
|
-
api_key: Optional[str],
|
|
44
|
-
extra_payload: Optional[Dict[str, Any]] = None,
|
|
45
|
-
) -> RequestParameters:
|
|
46
|
-
if api_key is None:
|
|
47
|
-
api_key = get_token()
|
|
48
|
-
if api_key is None:
|
|
49
|
-
raise ValueError(
|
|
50
|
-
"You must provide an api_key to work with Sambanova API or log in with `huggingface-cli login`."
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
# Route to the proxy if the api_key is a HF TOKEN
|
|
54
|
-
if api_key.startswith("hf_"):
|
|
55
|
-
base_url = constants.INFERENCE_PROXY_TEMPLATE.format(provider="sambanova")
|
|
56
|
-
logger.info("Calling Sambanova provider through Hugging Face proxy.")
|
|
57
|
-
else:
|
|
58
|
-
base_url = BASE_URL
|
|
59
|
-
logger.info("Calling Sambanova provider directly.")
|
|
60
|
-
headers = {**build_hf_headers(token=api_key), **headers}
|
|
61
|
-
|
|
62
|
-
mapped_model = self._map_model(model)
|
|
63
|
-
payload = {
|
|
64
|
-
"messages": inputs,
|
|
65
|
-
**{k: v for k, v in parameters.items() if v is not None},
|
|
66
|
-
"model": mapped_model,
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return RequestParameters(
|
|
70
|
-
url=f"{base_url}/v1/chat/completions",
|
|
71
|
-
task=self.task,
|
|
72
|
-
model=mapped_model,
|
|
73
|
-
json=payload,
|
|
74
|
-
data=None,
|
|
75
|
-
headers=headers,
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
def _map_model(self, model: Optional[str]) -> str:
|
|
79
|
-
if model is None:
|
|
80
|
-
raise ValueError("Please provide a model available on Sambanova.")
|
|
81
|
-
if self.task not in SUPPORTED_MODELS:
|
|
82
|
-
raise ValueError(f"Task {self.task} not supported with Sambanova.")
|
|
83
|
-
mapped_model = SUPPORTED_MODELS[self.task].get(model)
|
|
84
|
-
if mapped_model is None:
|
|
85
|
-
raise ValueError(f"Model {model} is not supported with Sambanova for task {self.task}.")
|
|
86
|
-
return mapped_model
|
|
87
|
-
|
|
88
|
-
def get_response(self, response: Union[bytes, Dict]) -> Any:
|
|
89
|
-
return response
|
|
6
|
+
super().__init__(provider="sambanova", base_url="https://api.sambanova.ai")
|
|
@@ -1,152 +1,58 @@
|
|
|
1
1
|
import base64
|
|
2
|
-
from abc import ABC
|
|
2
|
+
from abc import ABC
|
|
3
3
|
from typing import Any, Dict, Optional, Union
|
|
4
4
|
|
|
5
|
-
from huggingface_hub import
|
|
6
|
-
from huggingface_hub.inference._common import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"conversational": {
|
|
17
|
-
"databricks/dbrx-instruct": "databricks/dbrx-instruct",
|
|
18
|
-
"deepseek-ai/DeepSeek-R1": "deepseek-ai/DeepSeek-R1",
|
|
19
|
-
"deepseek-ai/DeepSeek-V3": "deepseek-ai/DeepSeek-V3",
|
|
20
|
-
"deepseek-ai/deepseek-llm-67b-chat": "deepseek-ai/deepseek-llm-67b-chat",
|
|
21
|
-
"google/gemma-2-9b-it": "google/gemma-2-9b-it",
|
|
22
|
-
"google/gemma-2b-it": "google/gemma-2-27b-it",
|
|
23
|
-
"meta-llama/Llama-2-13b-chat-hf": "meta-llama/Llama-2-13b-chat-hf",
|
|
24
|
-
"meta-llama/Llama-2-7b-chat-hf": "meta-llama/Llama-2-7b-chat-hf",
|
|
25
|
-
"meta-llama/Llama-3.2-11B-Vision-Instruct": "meta-llama/Llama-Vision-Free",
|
|
26
|
-
"meta-llama/Llama-3.2-3B-Instruct": "meta-llama/Llama-3.2-3B-Instruct-Turbo",
|
|
27
|
-
"meta-llama/Llama-3.2-90B-Vision-Instruct": "meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo",
|
|
28
|
-
"meta-llama/Llama-3.3-70B-Instruct": "meta-llama/Llama-3.3-70B-Instruct-Turbo",
|
|
29
|
-
"meta-llama/Meta-Llama-3-70B-Instruct": "meta-llama/Llama-3-70b-chat-hf",
|
|
30
|
-
"meta-llama/Meta-Llama-3-8B-Instruct": "meta-llama/Meta-Llama-3-8B-Instruct-Turbo",
|
|
31
|
-
"meta-llama/Meta-Llama-3.1-405B-Instruct": "meta-llama/Llama-3.2-11B-Vision-Instruct-Turbo",
|
|
32
|
-
"meta-llama/Meta-Llama-3.1-70B-Instruct": "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
|
|
33
|
-
"meta-llama/Meta-Llama-3.1-8B-Instruct": "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
|
|
34
|
-
"microsoft/WizardLM-2-8x22B": "microsoft/WizardLM-2-8x22B",
|
|
35
|
-
"mistralai/Mistral-7B-Instruct-v0.3": "mistralai/Mistral-7B-Instruct-v0.3",
|
|
36
|
-
"mistralai/Mixtral-8x22B-Instruct-v0.1": "mistralai/Mixtral-8x22B-Instruct-v0.1",
|
|
37
|
-
"mistralai/Mixtral-8x7B-Instruct-v0.1": "mistralai/Mixtral-8x7B-Instruct-v0.1",
|
|
38
|
-
"NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO": "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO",
|
|
39
|
-
"nvidia/Llama-3.1-Nemotron-70B-Instruct-HF": "nvidia/Llama-3.1-Nemotron-70B-Instruct-HF",
|
|
40
|
-
"Qwen/Qwen2-72B-Instruct": "Qwen/Qwen2-72B-Instruct",
|
|
41
|
-
"Qwen/Qwen2.5-72B-Instruct": "Qwen/Qwen2.5-72B-Instruct-Turbo",
|
|
42
|
-
"Qwen/Qwen2.5-7B-Instruct": "Qwen/Qwen2.5-7B-Instruct-Turbo",
|
|
43
|
-
"Qwen/Qwen2.5-Coder-32B-Instruct": "Qwen/Qwen2.5-Coder-32B-Instruct",
|
|
44
|
-
"Qwen/QwQ-32B-Preview": "Qwen/QwQ-32B-Preview",
|
|
45
|
-
"scb10x/llama-3-typhoon-v1.5-8b-instruct": "scb10x/scb10x-llama3-typhoon-v1-5-8b-instruct",
|
|
46
|
-
"scb10x/llama-3-typhoon-v1.5x-70b-instruct-awq": "scb10x/scb10x-llama3-typhoon-v1-5x-4f316",
|
|
47
|
-
},
|
|
48
|
-
"text-generation": {
|
|
49
|
-
"meta-llama/Llama-2-70b-hf": "meta-llama/Llama-2-70b-hf",
|
|
50
|
-
"meta-llama/Meta-Llama-3-8B": "meta-llama/Meta-Llama-3-8B",
|
|
51
|
-
"mistralai/Mixtral-8x7B-v0.1": "mistralai/Mixtral-8x7B-v0.1",
|
|
52
|
-
},
|
|
53
|
-
"text-to-image": {
|
|
54
|
-
"black-forest-labs/FLUX.1-Canny-dev": "black-forest-labs/FLUX.1-canny",
|
|
55
|
-
"black-forest-labs/FLUX.1-Depth-dev": "black-forest-labs/FLUX.1-depth",
|
|
56
|
-
"black-forest-labs/FLUX.1-dev": "black-forest-labs/FLUX.1-dev",
|
|
57
|
-
"black-forest-labs/FLUX.1-Redux-dev": "black-forest-labs/FLUX.1-redux",
|
|
58
|
-
"black-forest-labs/FLUX.1-schnell": "black-forest-labs/FLUX.1-pro",
|
|
59
|
-
"stabilityai/stable-diffusion-xl-base-1.0": "stabilityai/stable-diffusion-xl-base-1.0",
|
|
60
|
-
},
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
PER_TASK_ROUTES = {
|
|
65
|
-
"conversational": "v1/chat/completions",
|
|
66
|
-
"text-generation": "v1/completions",
|
|
67
|
-
"text-to-image": "v1/images/generations",
|
|
68
|
-
}
|
|
5
|
+
from huggingface_hub.inference._common import _as_dict
|
|
6
|
+
from huggingface_hub.inference._providers._common import (
|
|
7
|
+
BaseConversationalTask,
|
|
8
|
+
BaseTextGenerationTask,
|
|
9
|
+
TaskProviderHelper,
|
|
10
|
+
filter_none,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
_PROVIDER = "together"
|
|
15
|
+
_BASE_URL = "https://api.together.xyz"
|
|
69
16
|
|
|
70
17
|
|
|
71
18
|
class TogetherTask(TaskProviderHelper, ABC):
|
|
72
19
|
"""Base class for Together API tasks."""
|
|
73
20
|
|
|
74
21
|
def __init__(self, task: str):
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def prepare_request(
|
|
78
|
-
self,
|
|
79
|
-
*,
|
|
80
|
-
inputs: Any,
|
|
81
|
-
parameters: Dict[str, Any],
|
|
82
|
-
headers: Dict,
|
|
83
|
-
model: Optional[str],
|
|
84
|
-
api_key: Optional[str],
|
|
85
|
-
extra_payload: Optional[Dict[str, Any]] = None,
|
|
86
|
-
) -> RequestParameters:
|
|
87
|
-
if api_key is None:
|
|
88
|
-
api_key = get_token()
|
|
89
|
-
if api_key is None:
|
|
90
|
-
raise ValueError(
|
|
91
|
-
"You must provide an api_key to work with Together API or log in with `huggingface-cli login`."
|
|
92
|
-
)
|
|
93
|
-
headers = {**build_hf_headers(token=api_key), **headers}
|
|
94
|
-
|
|
95
|
-
# Route to the proxy if the api_key is a HF TOKEN
|
|
96
|
-
if api_key.startswith("hf_"):
|
|
97
|
-
base_url = constants.INFERENCE_PROXY_TEMPLATE.format(provider="together")
|
|
98
|
-
logger.info("Calling Together provider through Hugging Face proxy.")
|
|
99
|
-
else:
|
|
100
|
-
base_url = BASE_URL
|
|
101
|
-
logger.info("Calling Together provider directly.")
|
|
102
|
-
mapped_model = self._map_model(model)
|
|
103
|
-
if "model" in parameters:
|
|
104
|
-
parameters["model"] = mapped_model
|
|
105
|
-
payload = self._prepare_payload(inputs, parameters=parameters)
|
|
106
|
-
|
|
107
|
-
return RequestParameters(
|
|
108
|
-
url=f"{base_url}/{PER_TASK_ROUTES[self.task]}",
|
|
109
|
-
task=self.task,
|
|
110
|
-
model=mapped_model,
|
|
111
|
-
json=payload,
|
|
112
|
-
data=None,
|
|
113
|
-
headers=headers,
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
def _map_model(self, model: Optional[str]) -> str:
|
|
117
|
-
if model is None:
|
|
118
|
-
raise ValueError("Please provide a model available on Together.")
|
|
119
|
-
if self.task not in SUPPORTED_MODELS:
|
|
120
|
-
raise ValueError(f"Task {self.task} not supported with Together.")
|
|
121
|
-
mapped_model = SUPPORTED_MODELS[self.task].get(model)
|
|
122
|
-
if mapped_model is None:
|
|
123
|
-
raise ValueError(f"Model {model} is not supported with Together for task {self.task}.")
|
|
124
|
-
return mapped_model
|
|
22
|
+
super().__init__(provider=_PROVIDER, base_url=_BASE_URL, task=task)
|
|
125
23
|
|
|
126
|
-
def
|
|
127
|
-
|
|
24
|
+
def _prepare_route(self, mapped_model: str) -> str:
|
|
25
|
+
if self.task == "text-to-image":
|
|
26
|
+
return "/v1/images/generations"
|
|
27
|
+
elif self.task == "conversational":
|
|
28
|
+
return "/v1/chat/completions"
|
|
29
|
+
elif self.task == "text-generation":
|
|
30
|
+
return "/v1/completions"
|
|
31
|
+
raise ValueError(f"Unsupported task '{self.task}' for Together API.")
|
|
128
32
|
|
|
129
|
-
@abstractmethod
|
|
130
|
-
def _prepare_payload(self, inputs: Any, parameters: Dict[str, Any]) -> Dict[str, Any]: ...
|
|
131
33
|
|
|
34
|
+
class TogetherTextGenerationTask(BaseTextGenerationTask):
|
|
35
|
+
def __init__(self):
|
|
36
|
+
super().__init__(provider=_PROVIDER, base_url=_BASE_URL)
|
|
132
37
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def
|
|
136
|
-
|
|
38
|
+
|
|
39
|
+
class TogetherConversationalTask(BaseConversationalTask):
|
|
40
|
+
def __init__(self):
|
|
41
|
+
super().__init__(provider=_PROVIDER, base_url=_BASE_URL)
|
|
137
42
|
|
|
138
43
|
|
|
139
44
|
class TogetherTextToImageTask(TogetherTask):
|
|
140
45
|
def __init__(self):
|
|
141
46
|
super().__init__("text-to-image")
|
|
142
47
|
|
|
143
|
-
def
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
"
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
48
|
+
def _prepare_payload_as_dict(self, inputs: Any, parameters: Dict, mapped_model: str) -> Optional[Dict]:
|
|
49
|
+
parameters = filter_none(parameters)
|
|
50
|
+
if "num_inference_steps" in parameters:
|
|
51
|
+
parameters["steps"] = parameters.pop("num_inference_steps")
|
|
52
|
+
if "guidance_scale" in parameters:
|
|
53
|
+
parameters["guidance"] = parameters.pop("guidance_scale")
|
|
54
|
+
|
|
55
|
+
return {"prompt": inputs, "response_format": "base64", **parameters, "model": mapped_model}
|
|
150
56
|
|
|
151
57
|
def get_response(self, response: Union[bytes, Dict]) -> Any:
|
|
152
58
|
response_dict = _as_dict(response)
|
|
@@ -213,6 +213,11 @@ def _http_user_agent(
|
|
|
213
213
|
elif isinstance(user_agent, str):
|
|
214
214
|
ua += "; " + user_agent
|
|
215
215
|
|
|
216
|
+
# Retrieve user-agent origin headers from environment variable
|
|
217
|
+
origin = constants.HF_HUB_USER_AGENT_ORIGIN
|
|
218
|
+
if origin is not None:
|
|
219
|
+
ua += "; origin/" + origin
|
|
220
|
+
|
|
216
221
|
return _deduplicate_user_agent(ua)
|
|
217
222
|
|
|
218
223
|
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
"""Contain helper class to retrieve/store token from/to local cache."""
|
|
16
16
|
|
|
17
|
-
import warnings
|
|
18
17
|
from pathlib import Path
|
|
19
18
|
from typing import Optional
|
|
20
19
|
|
|
@@ -23,10 +22,6 @@ from ._auth import get_token
|
|
|
23
22
|
|
|
24
23
|
|
|
25
24
|
class HfFolder:
|
|
26
|
-
path_token = Path(constants.HF_TOKEN_PATH)
|
|
27
|
-
# Private attribute. Will be removed in v0.15
|
|
28
|
-
_old_path_token = Path(constants._OLD_HF_TOKEN_PATH)
|
|
29
|
-
|
|
30
25
|
# TODO: deprecate when adapted in transformers/datasets/gradio
|
|
31
26
|
# @_deprecate_method(version="1.0", message="Use `huggingface_hub.login` instead.")
|
|
32
27
|
@classmethod
|
|
@@ -41,8 +36,9 @@ class HfFolder:
|
|
|
41
36
|
token (`str`):
|
|
42
37
|
The token to save to the [`HfFolder`]
|
|
43
38
|
"""
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
path_token = Path(constants.HF_TOKEN_PATH)
|
|
40
|
+
path_token.parent.mkdir(parents=True, exist_ok=True)
|
|
41
|
+
path_token.write_text(token)
|
|
46
42
|
|
|
47
43
|
# TODO: deprecate when adapted in transformers/datasets/gradio
|
|
48
44
|
# @_deprecate_method(version="1.0", message="Use `huggingface_hub.get_token` instead.")
|
|
@@ -57,12 +53,6 @@ class HfFolder:
|
|
|
57
53
|
Returns:
|
|
58
54
|
`str` or `None`: The token, `None` if it doesn't exist.
|
|
59
55
|
"""
|
|
60
|
-
# 0. Check if token exist in old path but not new location
|
|
61
|
-
try:
|
|
62
|
-
cls._copy_to_new_path_and_warn()
|
|
63
|
-
except Exception: # if not possible (e.g. PermissionError), do not raise
|
|
64
|
-
pass
|
|
65
|
-
|
|
66
56
|
return get_token()
|
|
67
57
|
|
|
68
58
|
# TODO: deprecate when adapted in transformers/datasets/gradio
|
|
@@ -73,24 +63,6 @@ class HfFolder:
|
|
|
73
63
|
Deletes the token from storage. Does not fail if token does not exist.
|
|
74
64
|
"""
|
|
75
65
|
try:
|
|
76
|
-
|
|
77
|
-
except FileNotFoundError:
|
|
78
|
-
pass
|
|
79
|
-
|
|
80
|
-
try:
|
|
81
|
-
cls._old_path_token.unlink()
|
|
66
|
+
Path(constants.HF_TOKEN_PATH).unlink()
|
|
82
67
|
except FileNotFoundError:
|
|
83
68
|
pass
|
|
84
|
-
|
|
85
|
-
@classmethod
|
|
86
|
-
def _copy_to_new_path_and_warn(cls):
|
|
87
|
-
if cls._old_path_token.exists() and not cls.path_token.exists():
|
|
88
|
-
cls.save_token(cls._old_path_token.read_text())
|
|
89
|
-
warnings.warn(
|
|
90
|
-
f"A token has been found in `{cls._old_path_token}`. This is the old"
|
|
91
|
-
" path where tokens were stored. The new location is"
|
|
92
|
-
f" `{cls.path_token}` which is configurable using `HF_HOME` environment"
|
|
93
|
-
" variable. Your token has been copied to this new location. You can"
|
|
94
|
-
" now safely delete the old token file manually or use"
|
|
95
|
-
" `huggingface-cli logout`."
|
|
96
|
-
)
|
huggingface_hub/utils/_http.py
CHANGED
|
@@ -22,7 +22,8 @@ import time
|
|
|
22
22
|
import uuid
|
|
23
23
|
from functools import lru_cache
|
|
24
24
|
from http import HTTPStatus
|
|
25
|
-
from
|
|
25
|
+
from shlex import quote
|
|
26
|
+
from typing import Any, Callable, List, Optional, Tuple, Type, Union
|
|
26
27
|
|
|
27
28
|
import requests
|
|
28
29
|
from requests import HTTPError, Response
|
|
@@ -82,13 +83,15 @@ class UniqueRequestIdAdapter(HTTPAdapter):
|
|
|
82
83
|
request.headers[X_AMZN_TRACE_ID] = request.headers.get(X_REQUEST_ID) or str(uuid.uuid4())
|
|
83
84
|
|
|
84
85
|
# Add debug log
|
|
85
|
-
has_token = str(request.headers.get("authorization", ""))
|
|
86
|
+
has_token = len(str(request.headers.get("authorization", ""))) > 0
|
|
86
87
|
logger.debug(
|
|
87
88
|
f"Request {request.headers[X_AMZN_TRACE_ID]}: {request.method} {request.url} (authenticated: {has_token})"
|
|
88
89
|
)
|
|
89
90
|
|
|
90
91
|
def send(self, request: PreparedRequest, *args, **kwargs) -> Response:
|
|
91
92
|
"""Catch any RequestException to append request id to the error message for debugging."""
|
|
93
|
+
if constants.HF_DEBUG:
|
|
94
|
+
logger.debug(f"Send: {_curlify(request)}")
|
|
92
95
|
try:
|
|
93
96
|
return super().send(request, *args, **kwargs)
|
|
94
97
|
except requests.RequestException as e:
|
|
@@ -434,6 +437,7 @@ def hf_raise_for_status(response: Response, endpoint_name: Optional[str] = None)
|
|
|
434
437
|
|
|
435
438
|
elif error_code == "RepoNotFound" or (
|
|
436
439
|
response.status_code == 401
|
|
440
|
+
and error_message != "Invalid credentials in Authorization header"
|
|
437
441
|
and response.request is not None
|
|
438
442
|
and response.request.url is not None
|
|
439
443
|
and REPO_API_REGEX.search(response.request.url) is not None
|
|
@@ -549,3 +553,82 @@ def _format(error_type: Type[HfHubHTTPError], custom_message: str, response: Res
|
|
|
549
553
|
|
|
550
554
|
# Return
|
|
551
555
|
return error_type(final_error_message.strip(), response=response, server_message=server_message or None)
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
def _curlify(request: requests.PreparedRequest) -> str:
|
|
559
|
+
"""Convert a `requests.PreparedRequest` into a curl command (str).
|
|
560
|
+
|
|
561
|
+
Used for debug purposes only.
|
|
562
|
+
|
|
563
|
+
Implementation vendored from https://github.com/ofw/curlify/blob/master/curlify.py.
|
|
564
|
+
MIT License Copyright (c) 2016 Egor.
|
|
565
|
+
"""
|
|
566
|
+
parts: List[Tuple[Any, Any]] = [
|
|
567
|
+
("curl", None),
|
|
568
|
+
("-X", request.method),
|
|
569
|
+
]
|
|
570
|
+
|
|
571
|
+
for k, v in sorted(request.headers.items()):
|
|
572
|
+
if k.lower() == "authorization":
|
|
573
|
+
v = "<TOKEN>" # Hide authorization header, no matter its value (can be Bearer, Key, etc.)
|
|
574
|
+
parts += [("-H", "{0}: {1}".format(k, v))]
|
|
575
|
+
|
|
576
|
+
if request.body:
|
|
577
|
+
body = request.body
|
|
578
|
+
if isinstance(body, bytes):
|
|
579
|
+
body = body.decode("utf-8", errors="ignore")
|
|
580
|
+
if len(body) > 1000:
|
|
581
|
+
body = body[:1000] + " ... [truncated]"
|
|
582
|
+
parts += [("-d", body.replace("\n", ""))]
|
|
583
|
+
|
|
584
|
+
parts += [(None, request.url)]
|
|
585
|
+
|
|
586
|
+
flat_parts = []
|
|
587
|
+
for k, v in parts:
|
|
588
|
+
if k:
|
|
589
|
+
flat_parts.append(quote(k))
|
|
590
|
+
if v:
|
|
591
|
+
flat_parts.append(quote(v))
|
|
592
|
+
|
|
593
|
+
return " ".join(flat_parts)
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
# Regex to parse HTTP Range header
|
|
597
|
+
RANGE_REGEX = re.compile(r"^\s*bytes\s*=\s*(\d*)\s*-\s*(\d*)\s*$", re.IGNORECASE)
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
def _adjust_range_header(original_range: Optional[str], resume_size: int) -> Optional[str]:
|
|
601
|
+
"""
|
|
602
|
+
Adjust HTTP Range header to account for resume position.
|
|
603
|
+
"""
|
|
604
|
+
if not original_range:
|
|
605
|
+
return f"bytes={resume_size}-"
|
|
606
|
+
|
|
607
|
+
if "," in original_range:
|
|
608
|
+
raise ValueError(f"Multiple ranges detected - {original_range!r}, not supported yet.")
|
|
609
|
+
|
|
610
|
+
match = RANGE_REGEX.match(original_range)
|
|
611
|
+
if not match:
|
|
612
|
+
raise RuntimeError(f"Invalid range format - {original_range!r}.")
|
|
613
|
+
start, end = match.groups()
|
|
614
|
+
|
|
615
|
+
if not start:
|
|
616
|
+
if not end:
|
|
617
|
+
raise RuntimeError(f"Invalid range format - {original_range!r}.")
|
|
618
|
+
|
|
619
|
+
new_suffix = int(end) - resume_size
|
|
620
|
+
new_range = f"bytes=-{new_suffix}"
|
|
621
|
+
if new_suffix <= 0:
|
|
622
|
+
raise RuntimeError(f"Empty new range - {new_range!r}.")
|
|
623
|
+
return new_range
|
|
624
|
+
|
|
625
|
+
start = int(start)
|
|
626
|
+
new_start = start + resume_size
|
|
627
|
+
if end:
|
|
628
|
+
end = int(end)
|
|
629
|
+
new_range = f"bytes={new_start}-{end}"
|
|
630
|
+
if new_start > end:
|
|
631
|
+
raise RuntimeError(f"Empty new range - {new_range!r}.")
|
|
632
|
+
return new_range
|
|
633
|
+
|
|
634
|
+
return f"bytes={new_start}-"
|
huggingface_hub/utils/_typing.py
CHANGED
|
@@ -50,7 +50,7 @@ def is_jsonable(obj: Any) -> bool:
|
|
|
50
50
|
if isinstance(obj, (list, tuple)):
|
|
51
51
|
return all(is_jsonable(item) for item in obj)
|
|
52
52
|
if isinstance(obj, dict):
|
|
53
|
-
return all(isinstance(key,
|
|
53
|
+
return all(isinstance(key, _JSON_SERIALIZABLE_TYPES) and is_jsonable(value) for key, value in obj.items())
|
|
54
54
|
if hasattr(obj, "__json__"):
|
|
55
55
|
return True
|
|
56
56
|
return False
|
huggingface_hub/utils/logging.py
CHANGED
|
@@ -28,6 +28,8 @@ from logging import (
|
|
|
28
28
|
)
|
|
29
29
|
from typing import Optional
|
|
30
30
|
|
|
31
|
+
from .. import constants
|
|
32
|
+
|
|
31
33
|
|
|
32
34
|
log_levels = {
|
|
33
35
|
"debug": logging.DEBUG,
|
|
@@ -180,3 +182,7 @@ def enable_propagation() -> None:
|
|
|
180
182
|
|
|
181
183
|
|
|
182
184
|
_configure_library_root_logger()
|
|
185
|
+
|
|
186
|
+
if constants.HF_DEBUG:
|
|
187
|
+
# If `HF_DEBUG` environment variable is set, set the verbosity of `huggingface_hub` logger to `DEBUG`.
|
|
188
|
+
set_verbosity_debug()
|