Spaces:
Running on Zero
Running on Zero
Upload 31 files
Browse files- README.md +1 -1
- app.py +3 -2
- constants.py +1 -1
- dc.py +33 -0
- env.py +4 -0
- formatter.py +71 -43
- llmdolphin.py +0 -0
- llmenv.py +53 -2
- modutils.py +0 -0
- packages.txt +2 -1
- requirements.txt +6 -7
- tagger/fl2sd3longcap.py +22 -37
- tagger/florence2_compat.py +925 -0
- tagger/tagger.py +3 -2
- utils.py +35 -20
README.md
CHANGED
|
@@ -5,13 +5,13 @@ colorFrom: purple
|
|
| 5 |
colorTo: red
|
| 6 |
sdk: gradio
|
| 7 |
sdk_version: 5.45.0
|
|
|
|
| 8 |
app_file: app.py
|
| 9 |
license: mit
|
| 10 |
short_description: Text-to-Image
|
| 11 |
pinned: true
|
| 12 |
preload_from_hub:
|
| 13 |
- madebyollin/sdxl-vae-fp16-fix config.json,diffusion_pytorch_model.safetensors
|
| 14 |
-
hf_oauth: true
|
| 15 |
---
|
| 16 |
|
| 17 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 5 |
colorTo: red
|
| 6 |
sdk: gradio
|
| 7 |
sdk_version: 5.45.0
|
| 8 |
+
python_version: "3.10"
|
| 9 |
app_file: app.py
|
| 10 |
license: mit
|
| 11 |
short_description: Text-to-Image
|
| 12 |
pinned: true
|
| 13 |
preload_from_hub:
|
| 14 |
- madebyollin/sdxl-vae-fp16-fix config.json,diffusion_pytorch_model.safetensors
|
|
|
|
| 15 |
---
|
| 16 |
|
| 17 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
app.py
CHANGED
|
@@ -16,7 +16,9 @@ from dc import (infer, _infer, pass_result, get_diffusers_model_list, get_sample
|
|
| 16 |
# Translator
|
| 17 |
from llmdolphin import (dolphin_respond_auto, dolphin_parse_simple,
|
| 18 |
get_llm_formats, get_dolphin_model_format, get_dolphin_models, get_dolphin_loras, select_dolphin_lora, add_dolphin_loras,
|
| 19 |
-
get_dolphin_model_info, select_dolphin_model, select_dolphin_format, get_dolphin_sysprompt)
|
|
|
|
|
|
|
| 20 |
# Tagger
|
| 21 |
from tagger.v2 import v2_upsampling_prompt, V2_ALL_MODELS
|
| 22 |
from tagger.utils import (gradio_copy_text, gradio_copy_prompt, COPY_ACTION_JS,
|
|
@@ -681,7 +683,6 @@ with gr.Blocks(fill_width=True, elem_id="container", css=css) as demo:
|
|
| 681 |
with gr.Tab("Preprocessor", render=True):
|
| 682 |
preprocessor_tab()
|
| 683 |
|
| 684 |
-
gr.LoginButton()
|
| 685 |
gr.DuplicateButton(value="Duplicate Space for private use (This demo does not work on CPU. Requires GPU Space)")
|
| 686 |
|
| 687 |
if __name__ == "__main__":
|
|
|
|
| 16 |
# Translator
|
| 17 |
from llmdolphin import (dolphin_respond_auto, dolphin_parse_simple,
|
| 18 |
get_llm_formats, get_dolphin_model_format, get_dolphin_models, get_dolphin_loras, select_dolphin_lora, add_dolphin_loras,
|
| 19 |
+
get_dolphin_model_info, select_dolphin_model, select_dolphin_format, get_dolphin_sysprompt, initialize_llmdolphin_runtime)
|
| 20 |
+
initialize_llmdolphin_runtime()
|
| 21 |
+
|
| 22 |
# Tagger
|
| 23 |
from tagger.v2 import v2_upsampling_prompt, V2_ALL_MODELS
|
| 24 |
from tagger.utils import (gradio_copy_text, gradio_copy_prompt, COPY_ACTION_JS,
|
|
|
|
| 683 |
with gr.Tab("Preprocessor", render=True):
|
| 684 |
preprocessor_tab()
|
| 685 |
|
|
|
|
| 686 |
gr.DuplicateButton(value="Duplicate Space for private use (This demo does not work on CPU. Requires GPU Space)")
|
| 687 |
|
| 688 |
if __name__ == "__main__":
|
constants.py
CHANGED
|
@@ -19,7 +19,7 @@ DOWNLOAD_MODEL = "https://huggingface.co/zuv0/test/resolve/main/milkyWonderland_
|
|
| 19 |
DOWNLOAD_VAE = "https://huggingface.co/Anzhc/Anzhcs-VAEs/resolve/main/SDXL%20Anime%20VAE%20Dec-only%20B3.safetensors, https://huggingface.co/fp16-guy/anything_kl-f8-anime2_vae-ft-mse-840000-ema-pruned_blessed_clearvae_fp16_cleaned/resolve/main/vae-ft-mse-840000-ema-pruned_fp16.safetensors?download=true"
|
| 20 |
|
| 21 |
# - **Download LoRAs**
|
| 22 |
-
DOWNLOAD_LORA = "https://huggingface.co/Leopain/color/resolve/main/Coloring_book_-_LineArt.safetensors, https://civitai.com/api/download/models/135867, https://huggingface.co/Linaqruf/anime-detailer-xl-lora/resolve/main/anime-detailer-xl.safetensors?download=true, https://huggingface.co/Linaqruf/style-enhancer-xl-lora/resolve/main/style-enhancer-xl.safetensors?download=true
|
| 23 |
|
| 24 |
LOAD_DIFFUSERS_FORMAT_MODEL = [
|
| 25 |
'TestOrganizationPleaseIgnore/potato_quality_anime_plzwork_sdxl',
|
|
|
|
| 19 |
DOWNLOAD_VAE = "https://huggingface.co/Anzhc/Anzhcs-VAEs/resolve/main/SDXL%20Anime%20VAE%20Dec-only%20B3.safetensors, https://huggingface.co/fp16-guy/anything_kl-f8-anime2_vae-ft-mse-840000-ema-pruned_blessed_clearvae_fp16_cleaned/resolve/main/vae-ft-mse-840000-ema-pruned_fp16.safetensors?download=true"
|
| 20 |
|
| 21 |
# - **Download LoRAs**
|
| 22 |
+
DOWNLOAD_LORA = "https://huggingface.co/Leopain/color/resolve/main/Coloring_book_-_LineArt.safetensors, https://civitai.com/api/download/models/135867, https://huggingface.co/Linaqruf/anime-detailer-xl-lora/resolve/main/anime-detailer-xl.safetensors?download=true, https://huggingface.co/Linaqruf/style-enhancer-xl-lora/resolve/main/style-enhancer-xl.safetensors?download=true"
|
| 23 |
|
| 24 |
LOAD_DIFFUSERS_FORMAT_MODEL = [
|
| 25 |
'TestOrganizationPleaseIgnore/potato_quality_anime_plzwork_sdxl',
|
dc.py
CHANGED
|
@@ -181,6 +181,11 @@ class GuiSD:
|
|
| 181 |
# Avoid duplicate downloads
|
| 182 |
self.active_downloads = set()
|
| 183 |
self.download_lock = threading.Lock()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
def update_storage_models(self, storage_floor_gb=24, required_inventory_for_purge=3):
|
| 185 |
while get_used_storage_gb() > storage_floor_gb:
|
| 186 |
if len(self.inventory) < required_inventory_for_purge:
|
|
@@ -205,6 +210,34 @@ class GuiSD:
|
|
| 205 |
print(self.inventory)
|
| 206 |
|
| 207 |
def load_new_model(self, model_name, vae_model, task, controlnet_model, progress=gr.Progress(track_tqdm=True)):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 208 |
lock_key = model_name
|
| 209 |
|
| 210 |
while True:
|
|
|
|
| 181 |
# Avoid duplicate downloads
|
| 182 |
self.active_downloads = set()
|
| 183 |
self.download_lock = threading.Lock()
|
| 184 |
+
|
| 185 |
+
# Anti-abuse: track new model requests.
|
| 186 |
+
self.used_models = []
|
| 187 |
+
self.new_model_history = []
|
| 188 |
+
|
| 189 |
def update_storage_models(self, storage_floor_gb=24, required_inventory_for_purge=3):
|
| 190 |
while get_used_storage_gb() > storage_floor_gb:
|
| 191 |
if len(self.inventory) < required_inventory_for_purge:
|
|
|
|
| 210 |
print(self.inventory)
|
| 211 |
|
| 212 |
def load_new_model(self, model_name, vae_model, task, controlnet_model, progress=gr.Progress(track_tqdm=True)):
|
| 213 |
+
|
| 214 |
+
if model_name != model_list[0]:
|
| 215 |
+
# --- Anti-Abuse Check Start ---
|
| 216 |
+
if model_name in self.used_models:
|
| 217 |
+
# Move to the end to mark as the most recently used.
|
| 218 |
+
self.used_models.remove(model_name)
|
| 219 |
+
self.used_models.append(model_name)
|
| 220 |
+
else:
|
| 221 |
+
current_time = datetime.now()
|
| 222 |
+
# Retain history of new model requests from the last 20 minutes.
|
| 223 |
+
self.new_model_history = [
|
| 224 |
+
t for t in self.new_model_history
|
| 225 |
+
if (current_time - t).total_seconds() < 1200
|
| 226 |
+
]
|
| 227 |
+
|
| 228 |
+
# Allow a maximum of 5 new model requests per 20 minutes.
|
| 229 |
+
if len(self.new_model_history) >= 5:
|
| 230 |
+
yield "Rate limit exceeded: Too many new models requested."
|
| 231 |
+
raise gr.Error("Too many new models requested. Please reuse your previously loaded models or wait a few minutes before trying new ones.")
|
| 232 |
+
|
| 233 |
+
self.new_model_history.append(current_time)
|
| 234 |
+
self.used_models.append(model_name)
|
| 235 |
+
|
| 236 |
+
# Cap the reuse list to the 5 most recent models.
|
| 237 |
+
if len(self.used_models) > 5:
|
| 238 |
+
self.used_models.pop(0)
|
| 239 |
+
# --- Anti-Abuse Check End ---
|
| 240 |
+
|
| 241 |
lock_key = model_name
|
| 242 |
|
| 243 |
while True:
|
env.py
CHANGED
|
@@ -77,6 +77,10 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
|
|
| 77 |
'Raelina/Raehoshi-illust-XL-7',
|
| 78 |
'Raelina/Raehoshi-illust-XL-7.1',
|
| 79 |
'Raelina/Raehoshi-illust-XL-8',
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
'camenduru/FLUX.1-dev-diffusers',
|
| 81 |
'black-forest-labs/FLUX.1-schnell',
|
| 82 |
'sayakpaul/FLUX.1-merged',
|
|
|
|
| 77 |
'Raelina/Raehoshi-illust-XL-7',
|
| 78 |
'Raelina/Raehoshi-illust-XL-7.1',
|
| 79 |
'Raelina/Raehoshi-illust-XL-8',
|
| 80 |
+
'Raelina/Raehoshi-illust-XL-8.1',
|
| 81 |
+
'Raelina/Raehoshi-illust-XL-9',
|
| 82 |
+
'Raelina/Raehoshi-illust-XL-9.1',
|
| 83 |
+
'Raelina/Raehoshi-illust-vpred',
|
| 84 |
'camenduru/FLUX.1-dev-diffusers',
|
| 85 |
'black-forest-labs/FLUX.1-schnell',
|
| 86 |
'sayakpaul/FLUX.1-merged',
|
formatter.py
CHANGED
|
@@ -1,43 +1,71 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
)
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class LazyMessagesFormatterType:
|
| 2 |
+
def __getattr__(self, name):
|
| 3 |
+
return LazyLlamaAgentValue("MessagesFormatterType", name)
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
class LazyLlamaAgentValue:
|
| 7 |
+
def __init__(self, source, name):
|
| 8 |
+
self.source = source
|
| 9 |
+
self.name = name
|
| 10 |
+
|
| 11 |
+
def resolve(self):
|
| 12 |
+
if self.source == "MessagesFormatterType":
|
| 13 |
+
from llama_cpp_agent import MessagesFormatterType
|
| 14 |
+
return getattr(MessagesFormatterType, self.name)
|
| 15 |
+
if self.source == "custom_formatter":
|
| 16 |
+
return build_mistral_formatter(self.name)
|
| 17 |
+
raise ValueError(f"Unknown lazy llama agent value source: {self.source}")
|
| 18 |
+
|
| 19 |
+
def __repr__(self):
|
| 20 |
+
return f"<LazyLlamaAgentValue {self.source}.{self.name}>"
|
| 21 |
+
|
| 22 |
+
def __eq__(self, other):
|
| 23 |
+
return (
|
| 24 |
+
isinstance(other, LazyLlamaAgentValue)
|
| 25 |
+
and self.source == other.source
|
| 26 |
+
and self.name == other.name
|
| 27 |
+
)
|
| 28 |
+
|
| 29 |
+
def __hash__(self):
|
| 30 |
+
return hash((self.source, self.name))
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
MessagesFormatterType = LazyMessagesFormatterType()
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def build_mistral_formatter(name):
|
| 37 |
+
from llama_cpp_agent.messages_formatter import MessagesFormatter, PromptMarkers, Roles
|
| 38 |
+
|
| 39 |
+
if name == "mistral_v1":
|
| 40 |
+
markers = {
|
| 41 |
+
Roles.system: PromptMarkers(""" [INST]""", """ [/INST]"""),
|
| 42 |
+
Roles.user: PromptMarkers(""" [INST]""", """ [/INST]"""),
|
| 43 |
+
Roles.assistant: PromptMarkers(""" """, """</s>"""),
|
| 44 |
+
Roles.tool: PromptMarkers("", ""),
|
| 45 |
+
}
|
| 46 |
+
return MessagesFormatter("", markers, False, ["</s>"])
|
| 47 |
+
|
| 48 |
+
if name == "mistral_v2":
|
| 49 |
+
markers = {
|
| 50 |
+
Roles.system: PromptMarkers("""[INST] """, """[/INST]"""),
|
| 51 |
+
Roles.user: PromptMarkers("""[INST] """, """[/INST]"""),
|
| 52 |
+
Roles.assistant: PromptMarkers(""" """, """</s>"""),
|
| 53 |
+
Roles.tool: PromptMarkers("", ""),
|
| 54 |
+
}
|
| 55 |
+
return MessagesFormatter("", markers, False, ["</s>"])
|
| 56 |
+
|
| 57 |
+
if name == "mistral_v3_tekken":
|
| 58 |
+
markers = {
|
| 59 |
+
Roles.system: PromptMarkers("""[INST]""", """[/INST]"""),
|
| 60 |
+
Roles.user: PromptMarkers("""[INST]""", """[/INST]"""),
|
| 61 |
+
Roles.assistant: PromptMarkers("""""", """</s>"""),
|
| 62 |
+
Roles.tool: PromptMarkers("", ""),
|
| 63 |
+
}
|
| 64 |
+
return MessagesFormatter("", markers, False, ["</s>"])
|
| 65 |
+
|
| 66 |
+
raise ValueError(f"Unknown Mistral formatter: {name}")
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
mistral_v1_formatter = LazyLlamaAgentValue("custom_formatter", "mistral_v1")
|
| 70 |
+
mistral_v2_formatter = LazyLlamaAgentValue("custom_formatter", "mistral_v2")
|
| 71 |
+
mistral_v3_tekken_formatter = LazyLlamaAgentValue("custom_formatter", "mistral_v3_tekken")
|
llmdolphin.py
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
llmenv.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
| 1 |
-
from
|
| 2 |
-
from formatter import mistral_v1_formatter, mistral_v2_formatter, mistral_v3_tekken_formatter
|
| 3 |
from pathlib import Path
|
| 4 |
|
| 5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
llm_models = {
|
| 7 |
#"": ["", MessagesFormatterType.LLAMA_3],
|
| 8 |
#"": ["", MessagesFormatterType.MISTRAL],
|
|
@@ -161,8 +164,30 @@ llm_models = {
|
|
| 161 |
"claude-3.7-sonnet-reasoning-gemma3-12B.Q4_K_M.gguf": ["mradermacher/claude-3.7-sonnet-reasoning-gemma3-12B-GGUF", MessagesFormatterType.ALPACA],
|
| 162 |
"allura-org_MN-Lyrebird-12B-Q4_K_M.gguf": ["bartowski/allura-org_MN-Lyrebird-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 163 |
"ape-fiction-2-mistral-nemo.Q4_K_M.gguf": ["mradermacher/ape-fiction-2-mistral-nemo-GGUF", MessagesFormatterType.MISTRAL],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
"Irixxed_Homunculus-12B-Q3T-v.0.3-Reasoner.Q4_K_M.gguf": ["mradermacher/Irixxed_Homunculus-12B-Q3T-v.0.3-Reasoner-GGUF", MessagesFormatterType.MISTRAL],
|
| 165 |
"Gemma-2-Llama-Swallow-9b-pt-v0.1.Q4_K_M.gguf": ["mradermacher/Gemma-2-Llama-Swallow-9b-pt-v0.1-GGUF", MessagesFormatterType.ALPACA],
|
|
|
|
|
|
|
| 166 |
"Qwen2.5-7B-base-french-bespoke-stratos-full-sft.i1-Q5_K_S.gguf": ["mradermacher/Qwen2.5-7B-base-french-bespoke-stratos-full-sft-i1-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 167 |
"Protestant-Christian-Bible-Expert-v2.0-12B.Q4_K_M.gguf": ["mradermacher/Protestant-Christian-Bible-Expert-v2.0-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 168 |
"openbuddy-qwen2.5llamaify-14b-v23.1-200k.i1-Q4_K_M.gguf": ["mradermacher/openbuddy-qwen2.5llamaify-14b-v23.1-200k-i1-GGUF", MessagesFormatterType.OPEN_CHAT],
|
|
@@ -178,6 +203,29 @@ llm_models = {
|
|
| 178 |
#"": ["", MessagesFormatterType.OPEN_CHAT],
|
| 179 |
#"": ["", MessagesFormatterType.CHATML],
|
| 180 |
#"": ["", MessagesFormatterType.PHI_3],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 181 |
"SauerHuatuoSkyworkDeepWatt-o1-Llama-3.1-8B.Q5_K_M.gguf": ["mradermacher/SauerHuatuoSkyworkDeepWatt-o1-Llama-3.1-8B-GGUF", MessagesFormatterType.LLAMA_3],
|
| 182 |
"care-japanese-llama3.1-8b.Q5_K_M.gguf": ["mradermacher/care-japanese-llama3.1-8b-GGUF", MessagesFormatterType.LLAMA_3],
|
| 183 |
"UltraPatriMerge-12B.Q4_K_M.gguf": ["mradermacher/UltraPatriMerge-12B-GGUF", MessagesFormatterType.MISTRAL],
|
|
@@ -3838,8 +3886,11 @@ llm_loras = {str(Path(u).name): u for u in llm_loras_urls}
|
|
| 3838 |
llm_models_dir = "./llm_models"
|
| 3839 |
llm_loras_dir = "./llm_loras"
|
| 3840 |
|
|
|
|
|
|
|
| 3841 |
|
| 3842 |
llm_formats = {
|
|
|
|
| 3843 |
"MISTRAL": MessagesFormatterType.MISTRAL,
|
| 3844 |
"CHATML": MessagesFormatterType.CHATML,
|
| 3845 |
"VICUNA": MessagesFormatterType.VICUNA,
|
|
|
|
| 1 |
+
from formatter import MessagesFormatterType, mistral_v1_formatter, mistral_v2_formatter, mistral_v3_tekken_formatter
|
|
|
|
| 2 |
from pathlib import Path
|
| 3 |
|
| 4 |
|
| 5 |
+
GRADIO_DEBUG_ENV_NAME = "GRADIO_DEBUG"
|
| 6 |
+
LLMDOLPHIN_STATE_NAMESPACE = "__llmdolphin__"
|
| 7 |
+
|
| 8 |
+
|
| 9 |
llm_models = {
|
| 10 |
#"": ["", MessagesFormatterType.LLAMA_3],
|
| 11 |
#"": ["", MessagesFormatterType.MISTRAL],
|
|
|
|
| 164 |
"claude-3.7-sonnet-reasoning-gemma3-12B.Q4_K_M.gguf": ["mradermacher/claude-3.7-sonnet-reasoning-gemma3-12B-GGUF", MessagesFormatterType.ALPACA],
|
| 165 |
"allura-org_MN-Lyrebird-12B-Q4_K_M.gguf": ["bartowski/allura-org_MN-Lyrebird-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 166 |
"ape-fiction-2-mistral-nemo.Q4_K_M.gguf": ["mradermacher/ape-fiction-2-mistral-nemo-GGUF", MessagesFormatterType.MISTRAL],
|
| 167 |
+
"Shadow-Crystal-12B.Q4_K_M.gguf": ["mradermacher/Shadow-Crystal-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 168 |
+
"Starry-Shadow-12B.Q4_K_M.gguf": ["mradermacher/Starry-Shadow-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 169 |
+
"Radiant-Shadow-12B.Q4_K_M.gguf": ["mradermacher/Radiant-Shadow-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 170 |
+
"Arsenic-Shahrazad-12B-v3.i1-Q4_K_M.gguf": ["mradermacher/Arsenic-Shahrazad-12B-v3-i1-GGUF", MessagesFormatterType.MISTRAL],
|
| 171 |
+
"Mistral-Nemo-2407-Instruct-12B-Deep-Thinking-Claude-Gemini-GPT5.2.i1-Q4_K_M.gguf": ["mradermacher/Mistral-Nemo-2407-Instruct-12B-Deep-Thinking-Claude-Gemini-GPT5.2-i1-GGUF", MessagesFormatterType.MISTRAL],
|
| 172 |
+
"Lunar-Abyss-12B.Q4_K_S.gguf": ["mradermacher/Lunar-Abyss-12B-GGUF", MessagesFormatterType.CHATML],
|
| 173 |
+
"prototype-x-12b-q6_k.gguf": ["Vortex5/Prototype-X-12b-Q6_K-GGUF", MessagesFormatterType.MISTRAL],
|
| 174 |
+
"gemma-3n-E4B-it-PaperWitch-heresy.i1-Q4_K_M.gguf": ["mradermacher/gemma-3n-E4B-it-PaperWitch-heresy-i1-GGUF", MessagesFormatterType.ALPACA],
|
| 175 |
+
"Violet-Mist-12B.i1-Q4_K_M.gguf": ["mradermacher/Violet-Mist-12B-i1-GGUF", MessagesFormatterType.MISTRAL],
|
| 176 |
+
"TheStoryteller-12B.i1-Q4_K_M.gguf": ["mradermacher/TheStoryteller-12B-i1-GGUF", MessagesFormatterType.CHATML],
|
| 177 |
+
"Dreamstar-12B.Q4_K_M.gguf": ["mradermacher/Dreamstar-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 178 |
+
"Mistral-Nemo-Instruct-2407-heretic-noslop-MPOA.Q4_K_M.gguf": ["mradermacher/Mistral-Nemo-Instruct-2407-heretic-noslop-MPOA-GGUF", MessagesFormatterType.MISTRAL],
|
| 179 |
+
"Equatorium-v3-12B.Q4_K_M.gguf": ["mradermacher/Equatorium-v3-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 180 |
+
"RPBizkit-v6-12B.Q4_K_M.gguf": ["mradermacher/RPBizkit-v6-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 181 |
+
"MN-VelvetCafe-RP-12B.i1-Q4_K_M.gguf": ["mradermacher/MN-VelvetCafe-RP-12B-i1-GGUF", MessagesFormatterType.CHATML],
|
| 182 |
+
"Aurora-Mirage-12B.Q4_K_M.gguf": ["mradermacher/Aurora-Mirage-12B-GGUF", MessagesFormatterType.CHATML],
|
| 183 |
+
"littlemonster-reasoning-12B-QKVO-heretic-HF.Q4_K_M.gguf": ["mradermacher/littlemonster-reasoning-12B-QKVO-heretic-HF-GGUF", MessagesFormatterType.ALPACA],
|
| 184 |
+
"QuasiStarSynth-12B-absolute-heresy.Q4_K_M.gguf": ["mradermacher/QuasiStarSynth-12B-absolute-heresy-GGUF", MessagesFormatterType.CHATML],
|
| 185 |
+
"ColdBrew-Nemo-12B-Arcane-Fusion-Combined-Thinker.Q4_K_M.gguf": ["mradermacher/ColdBrew-Nemo-12B-Arcane-Fusion-Combined-Thinker-GGUF", MessagesFormatterType.MISTRAL],
|
| 186 |
+
"AuroSlayerEtherealKrixUnslopMellRPMaxDARKNESS-12B.i1-Q4_K_M.gguf": ["mradermacher/AuroSlayerEtherealKrixUnslopMellRPMaxDARKNESS-12B-i1-GGUF", MessagesFormatterType.MISTRAL],
|
| 187 |
"Irixxed_Homunculus-12B-Q3T-v.0.3-Reasoner.Q4_K_M.gguf": ["mradermacher/Irixxed_Homunculus-12B-Q3T-v.0.3-Reasoner-GGUF", MessagesFormatterType.MISTRAL],
|
| 188 |
"Gemma-2-Llama-Swallow-9b-pt-v0.1.Q4_K_M.gguf": ["mradermacher/Gemma-2-Llama-Swallow-9b-pt-v0.1-GGUF", MessagesFormatterType.ALPACA],
|
| 189 |
+
"Tlacuilo-12B.Q4_K_M.gguf": ["mradermacher/Tlacuilo-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 190 |
+
"Nemo-Instruct-2407-MPOA-v4-12B.i1-Q4_K_M.gguf": ["mradermacher/Nemo-Instruct-2407-MPOA-v4-12B-i1-GGUF", MessagesFormatterType.MISTRAL],
|
| 191 |
"Qwen2.5-7B-base-french-bespoke-stratos-full-sft.i1-Q5_K_S.gguf": ["mradermacher/Qwen2.5-7B-base-french-bespoke-stratos-full-sft-i1-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 192 |
"Protestant-Christian-Bible-Expert-v2.0-12B.Q4_K_M.gguf": ["mradermacher/Protestant-Christian-Bible-Expert-v2.0-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 193 |
"openbuddy-qwen2.5llamaify-14b-v23.1-200k.i1-Q4_K_M.gguf": ["mradermacher/openbuddy-qwen2.5llamaify-14b-v23.1-200k-i1-GGUF", MessagesFormatterType.OPEN_CHAT],
|
|
|
|
| 203 |
#"": ["", MessagesFormatterType.OPEN_CHAT],
|
| 204 |
#"": ["", MessagesFormatterType.CHATML],
|
| 205 |
#"": ["", MessagesFormatterType.PHI_3],
|
| 206 |
+
"Equatorium-v2-12B.Q4_K_M.gguf": ["mradermacher/Equatorium-v2-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 207 |
+
"Mangione-12B-Model_Stock.Q4_K_M.gguf": ["mradermacher/Mangione-12B-Model_Stock-GGUF", MessagesFormatterType.MISTRAL],
|
| 208 |
+
"gemma-3-12b-it-biprojected-abliterated.Q4_K_M.gguf": ["mradermacher/gemma-3-12b-it-biprojected-abliterated-GGUF", MessagesFormatterType.ALPACA],
|
| 209 |
+
"mistralai-Mistral-Nemo-Instruct-2407-extensive-BP-abliteration-12B.Q4_K_M.gguf": ["mradermacher/mistralai-Mistral-Nemo-Instruct-2407-extensive-BP-abliteration-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 210 |
+
"PokeeAI_pokee_research_7b-Q5_K_M.gguf": ["bartowski/PokeeAI_pokee_research_7b-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 211 |
+
"FARE-8B.Q5_K_M.gguf": ["mradermacher/FARE-8B-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 212 |
+
"AdaVaR-3B.Q5_K_M.gguf": ["mradermacher/AdaVaR-3B-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 213 |
+
"Qwen2.5-14B-Valor.Q4_K_M.gguf": ["mradermacher/Qwen2.5-14B-Valor-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 214 |
+
"ukko-thinking-3.09b-v1.i1-Q5_K_M.gguf": ["mradermacher/ukko-thinking-3.09b-v1-i1-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 215 |
+
"Logos-3B.Q5_K_M.gguf": ["mradermacher/Logos-3B-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 216 |
+
"ReSeek-qwen2.5-7b-em-grpo.Q5_K_M.gguf": ["mradermacher/ReSeek-qwen2.5-7b-em-grpo-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 217 |
+
"VideoChat-R1_5.Q5_K_M.gguf": ["mradermacher/VideoChat-R1_5-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 218 |
+
"zen-eco-4b-instruct.i1-Q5_K_M.gguf": ["mradermacher/zen-eco-4b-instruct-i1-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 219 |
+
"nytheria-3b.i1-Q5_K_M.gguf": ["mradermacher/nytheria-3b-i1-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 220 |
+
"VideoJudgeR-3B.Q5_K_M.gguf": ["mradermacher/VideoJudgeR-3B-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 221 |
+
"Magrathic-12B.Q4_K_M.gguf": ["mradermacher/Magrathic-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 222 |
+
"phoenix-core-v1.0.Q4_K_M.gguf": ["mradermacher/phoenix-core-v1.0-GGUF", MessagesFormatterType.MISTRAL],
|
| 223 |
+
"GUI-G1-3B-v1.Q5_K_M.gguf": ["mradermacher/GUI-G1-3B-v1-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 224 |
+
"Impish-Irix-Kitsune.Q4_K_M.gguf": ["mradermacher/Impish-Irix-Kitsune-GGUF", MessagesFormatterType.MISTRAL],
|
| 225 |
+
"L3.3-Nemoblated-8B-V0.1.i1-Q5_K_M.gguf": ["mradermacher/L3.3-Nemoblated-8B-V0.1-i1-GGUF", MessagesFormatterType.LLAMA_3],
|
| 226 |
+
"Luna-Karcher-12B.Q4_K_M.gguf": ["mradermacher/Luna-Karcher-12B-GGUF", MessagesFormatterType.MISTRAL],
|
| 227 |
+
"Chimera-DeepSeek-NSFW-8B.Q5_K_M.gguf": ["mradermacher/Chimera-DeepSeek-NSFW-8B-GGUF", MessagesFormatterType.LLAMA_3],
|
| 228 |
+
"Toolbox-sft-3B.Q5_K_M.gguf": ["mradermacher/Toolbox-sft-3B-GGUF", MessagesFormatterType.OPEN_CHAT],
|
| 229 |
"SauerHuatuoSkyworkDeepWatt-o1-Llama-3.1-8B.Q5_K_M.gguf": ["mradermacher/SauerHuatuoSkyworkDeepWatt-o1-Llama-3.1-8B-GGUF", MessagesFormatterType.LLAMA_3],
|
| 230 |
"care-japanese-llama3.1-8b.Q5_K_M.gguf": ["mradermacher/care-japanese-llama3.1-8b-GGUF", MessagesFormatterType.LLAMA_3],
|
| 231 |
"UltraPatriMerge-12B.Q4_K_M.gguf": ["mradermacher/UltraPatriMerge-12B-GGUF", MessagesFormatterType.MISTRAL],
|
|
|
|
| 3886 |
llm_models_dir = "./llm_models"
|
| 3887 |
llm_loras_dir = "./llm_loras"
|
| 3888 |
|
| 3889 |
+
LLM_FORMAT_AUTO_GGUF_DEFAULT = "__GGUF_DEFAULT__"
|
| 3890 |
+
|
| 3891 |
|
| 3892 |
llm_formats = {
|
| 3893 |
+
"AUTO (GGUF DEFAULT)": LLM_FORMAT_AUTO_GGUF_DEFAULT,
|
| 3894 |
"MISTRAL": MessagesFormatterType.MISTRAL,
|
| 3895 |
"CHATML": MessagesFormatterType.CHATML,
|
| 3896 |
"VICUNA": MessagesFormatterType.VICUNA,
|
modutils.py
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
packages.txt
CHANGED
|
@@ -1 +1,2 @@
|
|
| 1 |
-
git-lfs
|
|
|
|
|
|
| 1 |
+
git-lfs
|
| 2 |
+
ffmpeg
|
requirements.txt
CHANGED
|
@@ -2,19 +2,17 @@ stablepy==0.6.5
|
|
| 2 |
diffusers
|
| 3 |
transformers
|
| 4 |
accelerate
|
| 5 |
-
torch==2.
|
| 6 |
numpy<2
|
| 7 |
gdown
|
| 8 |
opencv-python
|
| 9 |
huggingface_hub
|
| 10 |
-
|
| 11 |
-
hf_transfer
|
| 12 |
scikit-build-core
|
| 13 |
-
https://github.com/
|
| 14 |
git+https://github.com/John6666cat/llama-cpp-agent
|
| 15 |
pybind11>=2.12
|
| 16 |
rapidfuzz
|
| 17 |
-
torchvision
|
| 18 |
optimum[onnxruntime]
|
| 19 |
#dartrs
|
| 20 |
git+https://github.com/John6666cat/dartrs
|
|
@@ -24,5 +22,6 @@ wrapt-timeout-decorator
|
|
| 24 |
sentencepiece
|
| 25 |
unidecode
|
| 26 |
matplotlib-inline
|
| 27 |
-
|
| 28 |
-
|
|
|
|
|
|
| 2 |
diffusers
|
| 3 |
transformers
|
| 4 |
accelerate
|
| 5 |
+
torch==2.8.0
|
| 6 |
numpy<2
|
| 7 |
gdown
|
| 8 |
opencv-python
|
| 9 |
huggingface_hub
|
| 10 |
+
spaces
|
|
|
|
| 11 |
scikit-build-core
|
| 12 |
+
https://github.com/John6666cat/llama-cpp-python/releases/download/v0.3.35-cu128-Basic-linux-20260412/llama_cpp_python-0.3.35+cu128.basic-cp310-cp310-linux_x86_64.whl
|
| 13 |
git+https://github.com/John6666cat/llama-cpp-agent
|
| 14 |
pybind11>=2.12
|
| 15 |
rapidfuzz
|
|
|
|
| 16 |
optimum[onnxruntime]
|
| 17 |
#dartrs
|
| 18 |
git+https://github.com/John6666cat/dartrs
|
|
|
|
| 22 |
sentencepiece
|
| 23 |
unidecode
|
| 24 |
matplotlib-inline
|
| 25 |
+
mediapipe==0.10.5
|
| 26 |
+
einops
|
| 27 |
+
# pydantic==2.10.6
|
tagger/fl2sd3longcap.py
CHANGED
|
@@ -1,49 +1,34 @@
|
|
| 1 |
-
import spaces
|
| 2 |
-
from transformers import AutoProcessor, AutoModelForCausalLM
|
| 3 |
import re
|
| 4 |
-
|
|
|
|
| 5 |
import torch
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
-
from transformers.utils import is_flash_attn_2_available
|
| 8 |
-
if not is_flash_attn_2_available():
|
| 9 |
-
import subprocess
|
| 10 |
-
subprocess.run('pip install flash-attn --no-build-isolation', env={'FLASH_ATTENTION_SKIP_CUDA_BUILD': "TRUE"}, shell=True)
|
| 11 |
|
| 12 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 13 |
|
| 14 |
try:
|
| 15 |
-
fl_model =
|
| 16 |
-
fl_processor = AutoProcessor.from_pretrained('gokaygokay/Florence-2-SD3-Captioner', trust_remote_code=True)
|
| 17 |
except Exception as e:
|
| 18 |
print(e)
|
| 19 |
fl_model = fl_processor = None
|
|
|
|
|
|
|
| 20 |
|
| 21 |
def fl_modify_caption(caption: str) -> str:
|
| 22 |
-
"""
|
| 23 |
-
Removes specific prefixes from captions if present, otherwise returns the original caption.
|
| 24 |
-
Args:
|
| 25 |
-
caption (str): A string containing a caption.
|
| 26 |
-
Returns:
|
| 27 |
-
str: The caption with the prefix removed if it was present, or the original caption.
|
| 28 |
-
"""
|
| 29 |
-
# Define the prefixes to remove
|
| 30 |
prefix_substrings = [
|
| 31 |
('captured from ', ''),
|
| 32 |
-
('captured at ', '')
|
| 33 |
]
|
| 34 |
-
|
| 35 |
-
# Create a regex pattern to match any of the prefixes
|
| 36 |
pattern = '|'.join([re.escape(opening) for opening, _ in prefix_substrings])
|
| 37 |
replacers = {opening.lower(): replacer for opening, replacer in prefix_substrings}
|
| 38 |
-
|
| 39 |
-
# Function to replace matched prefix with its corresponding replacement
|
| 40 |
def replace_fn(match):
|
| 41 |
return replacers[match.group(0).lower()]
|
| 42 |
-
|
| 43 |
-
# Apply the regex to the caption
|
| 44 |
modified_caption = re.sub(pattern, replace_fn, caption, count=1, flags=re.IGNORECASE)
|
| 45 |
-
|
| 46 |
-
# If the caption was modified, return the modified version; otherwise, return the original
|
| 47 |
return modified_caption if modified_caption != caption else caption
|
| 48 |
|
| 49 |
|
|
@@ -52,32 +37,32 @@ def fl_run_example(image):
|
|
| 52 |
task_prompt = "<DESCRIPTION>"
|
| 53 |
prompt = task_prompt + "Describe this image in great detail."
|
| 54 |
|
| 55 |
-
# Ensure the image is in RGB mode
|
| 56 |
if image.mode != "RGB":
|
| 57 |
image = image.convert("RGB")
|
| 58 |
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
generated_ids = fl_model.generate(
|
| 62 |
input_ids=inputs["input_ids"],
|
|
|
|
| 63 |
pixel_values=inputs["pixel_values"],
|
| 64 |
-
max_new_tokens=1024,
|
| 65 |
-
num_beams=3
|
| 66 |
)
|
| 67 |
-
fl_model.to("cpu")
|
| 68 |
generated_text = fl_processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
|
| 69 |
-
parsed_answer = fl_processor.post_process_generation(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 70 |
return fl_modify_caption(parsed_answer["<DESCRIPTION>"])
|
| 71 |
|
| 72 |
|
| 73 |
def predict_tags_fl2_sd3(image: Image.Image, input_tags: str, algo: list[str]):
|
| 74 |
def to_list(s):
|
| 75 |
return [x.strip() for x in s.split(",") if not s == ""]
|
| 76 |
-
|
| 77 |
def list_uniq(l):
|
| 78 |
return sorted(set(l), key=l.index)
|
| 79 |
-
|
| 80 |
-
if
|
| 81 |
return input_tags
|
| 82 |
tag_list = list_uniq(to_list(input_tags) + to_list(fl_run_example(image) + ", "))
|
| 83 |
tag_list.remove("")
|
|
|
|
|
|
|
|
|
|
| 1 |
import re
|
| 2 |
+
|
| 3 |
+
import spaces
|
| 4 |
import torch
|
| 5 |
+
from PIL import Image
|
| 6 |
+
|
| 7 |
+
from tagger.florence2_compat import generate_florence2, load_florence2_bundle, prepare_florence2_inputs
|
| 8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
|
| 10 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 11 |
|
| 12 |
try:
|
| 13 |
+
fl_model, fl_processor, fl_audit = load_florence2_bundle('gokaygokay/Florence-2-SD3-Captioner', device)
|
|
|
|
| 14 |
except Exception as e:
|
| 15 |
print(e)
|
| 16 |
fl_model = fl_processor = None
|
| 17 |
+
fl_audit = {"load_error": repr(e)}
|
| 18 |
+
|
| 19 |
|
| 20 |
def fl_modify_caption(caption: str) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
prefix_substrings = [
|
| 22 |
('captured from ', ''),
|
| 23 |
+
('captured at ', ''),
|
| 24 |
]
|
|
|
|
|
|
|
| 25 |
pattern = '|'.join([re.escape(opening) for opening, _ in prefix_substrings])
|
| 26 |
replacers = {opening.lower(): replacer for opening, replacer in prefix_substrings}
|
| 27 |
+
|
|
|
|
| 28 |
def replace_fn(match):
|
| 29 |
return replacers[match.group(0).lower()]
|
| 30 |
+
|
|
|
|
| 31 |
modified_caption = re.sub(pattern, replace_fn, caption, count=1, flags=re.IGNORECASE)
|
|
|
|
|
|
|
| 32 |
return modified_caption if modified_caption != caption else caption
|
| 33 |
|
| 34 |
|
|
|
|
| 37 |
task_prompt = "<DESCRIPTION>"
|
| 38 |
prompt = task_prompt + "Describe this image in great detail."
|
| 39 |
|
|
|
|
| 40 |
if image.mode != "RGB":
|
| 41 |
image = image.convert("RGB")
|
| 42 |
|
| 43 |
+
inputs = prepare_florence2_inputs(fl_processor, fl_model, prompt, image, device)
|
| 44 |
+
generated_ids = generate_florence2(fl_model,
|
|
|
|
| 45 |
input_ids=inputs["input_ids"],
|
| 46 |
+
attention_mask=inputs.get("attention_mask"),
|
| 47 |
pixel_values=inputs["pixel_values"],
|
|
|
|
|
|
|
| 48 |
)
|
|
|
|
| 49 |
generated_text = fl_processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
|
| 50 |
+
parsed_answer = fl_processor.post_process_generation(
|
| 51 |
+
generated_text,
|
| 52 |
+
task=task_prompt,
|
| 53 |
+
image_size=(image.width, image.height),
|
| 54 |
+
)
|
| 55 |
return fl_modify_caption(parsed_answer["<DESCRIPTION>"])
|
| 56 |
|
| 57 |
|
| 58 |
def predict_tags_fl2_sd3(image: Image.Image, input_tags: str, algo: list[str]):
|
| 59 |
def to_list(s):
|
| 60 |
return [x.strip() for x in s.split(",") if not s == ""]
|
| 61 |
+
|
| 62 |
def list_uniq(l):
|
| 63 |
return sorted(set(l), key=l.index)
|
| 64 |
+
|
| 65 |
+
if "Use Florence-2-SD3-Long-Captioner" not in algo:
|
| 66 |
return input_tags
|
| 67 |
tag_list = list_uniq(to_list(input_tags) + to_list(fl_run_example(image) + ", "))
|
| 68 |
tag_list.remove("")
|
tagger/florence2_compat.py
ADDED
|
@@ -0,0 +1,925 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import copy
|
| 2 |
+
import functools
|
| 3 |
+
import gc
|
| 4 |
+
import json
|
| 5 |
+
import os
|
| 6 |
+
import re
|
| 7 |
+
import types
|
| 8 |
+
from typing import Any, Dict, Iterable, Optional, Tuple
|
| 9 |
+
|
| 10 |
+
import torch
|
| 11 |
+
import transformers
|
| 12 |
+
from transformers import AutoProcessor
|
| 13 |
+
from transformers.tokenization_utils_base import AddedToken
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
try:
|
| 17 |
+
from huggingface_hub import snapshot_download
|
| 18 |
+
except Exception:
|
| 19 |
+
snapshot_download = None
|
| 20 |
+
|
| 21 |
+
try:
|
| 22 |
+
from safetensors.torch import load_file as load_safetensors_file
|
| 23 |
+
except Exception:
|
| 24 |
+
load_safetensors_file = None
|
| 25 |
+
|
| 26 |
+
try:
|
| 27 |
+
from transformers import AutoModelForCausalLM, Florence2ForConditionalGeneration
|
| 28 |
+
except Exception:
|
| 29 |
+
AutoModelForCausalLM = None
|
| 30 |
+
Florence2ForConditionalGeneration = None
|
| 31 |
+
|
| 32 |
+
try:
|
| 33 |
+
from transformers.generation.utils import GenerationMixin
|
| 34 |
+
except Exception:
|
| 35 |
+
GenerationMixin = None
|
| 36 |
+
|
| 37 |
+
try:
|
| 38 |
+
from transformers.models.auto.auto_factory import add_generation_mixin_to_remote_model
|
| 39 |
+
except Exception:
|
| 40 |
+
add_generation_mixin_to_remote_model = None
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
_IMAGE_TOKEN = "<image>"
|
| 44 |
+
|
| 45 |
+
# Florence2 compat settings. Keep these as plain module constants for easier HF Space maintenance.
|
| 46 |
+
FLORENCE2_LEGACY_ATTN_IMPLEMENTATION = "eager"
|
| 47 |
+
FLORENCE2_LEGACY_USE_CACHE = True
|
| 48 |
+
FLORENCE2_LEGACY_MAX_NUM_BEAMS = 1
|
| 49 |
+
FLORENCE2_PROCESSOR_USE_FAST = False
|
| 50 |
+
FLORENCE2_GENERATE_DEFAULT_MAX_NEW_TOKENS = 512
|
| 51 |
+
FLORENCE2_GENERATE_DEFAULT_NUM_BEAMS = 3
|
| 52 |
+
FLORENCE2_GENERATE_MAX_NEW_TOKENS_BY_REPO = {
|
| 53 |
+
"MiaoshouAI/Florence-2-large-PromptGen-v2.0": 256,
|
| 54 |
+
"gokaygokay/Florence-2-SD3-Captioner": 384,
|
| 55 |
+
"gokaygokay/Florence-2-Flux": 384,
|
| 56 |
+
"gokaygokay/Florence-2-Flux-Large": 384,
|
| 57 |
+
"thwri/CogFlorence-2.2-Large": 512,
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
# Pin the currently working Florence checkpoints so trust_remote_code fetches stay reproducible.
|
| 61 |
+
FLORENCE2_REVISIONS = {
|
| 62 |
+
"gokaygokay/Florence-2-Flux": "d17454c4e4bccb3bfe52477634089b8515b1bc3c",
|
| 63 |
+
"gokaygokay/Florence-2-Flux-Large": "ed3af3df6d23d9f25d1dd4ce05ba95bb43c37209",
|
| 64 |
+
"gokaygokay/Florence-2-SD3-Captioner": "178fd612533079793c33ede7245b29d23db307b5",
|
| 65 |
+
"thwri/CogFlorence-2.2-Large": "19f2c614fdfd18ba49c81d567d70d3a68313e0bb",
|
| 66 |
+
"MiaoshouAI/Florence-2-large-PromptGen-v2.0": "4aa33eaf50aab040fe8523312ff52eb53322c220",
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
# Cog processor is the only unstable case. Try the model repo first as documented,
|
| 70 |
+
# then fall back to upstream Florence processor sources.
|
| 71 |
+
FLORENCE2_PROCESSOR_CANDIDATES = {
|
| 72 |
+
"thwri/CogFlorence-2.2-Large": [
|
| 73 |
+
{
|
| 74 |
+
"repo_id": "thwri/CogFlorence-2.2-Large",
|
| 75 |
+
"trust_remote_code": True,
|
| 76 |
+
"revision": "19f2c614fdfd18ba49c81d567d70d3a68313e0bb",
|
| 77 |
+
},
|
| 78 |
+
{
|
| 79 |
+
"repo_id": "microsoft/Florence-2-large",
|
| 80 |
+
"trust_remote_code": True,
|
| 81 |
+
"revision": "00d2f1570b00c6dea5df998f5635db96840436bc",
|
| 82 |
+
},
|
| 83 |
+
{
|
| 84 |
+
"repo_id": "microsoft/Florence-2-large",
|
| 85 |
+
"trust_remote_code": False,
|
| 86 |
+
},
|
| 87 |
+
],
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def _major_version() -> int:
|
| 92 |
+
m = re.match(r"(\d+)", getattr(transformers, "__version__", "0"))
|
| 93 |
+
return int(m.group(1)) if m else 0
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def _dtype_kwargs(device: str) -> Dict[str, Any]:
|
| 97 |
+
dtype = torch.float16 if device == "cuda" else torch.float32
|
| 98 |
+
if _major_version() >= 5:
|
| 99 |
+
return {"dtype": dtype}
|
| 100 |
+
return {"torch_dtype": dtype}
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def _revision_kwargs(repo_id: str) -> Dict[str, Any]:
|
| 104 |
+
revision = FLORENCE2_REVISIONS.get(repo_id)
|
| 105 |
+
if not revision:
|
| 106 |
+
return {}
|
| 107 |
+
return {"revision": revision, "code_revision": revision}
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
def _processor_candidates(repo_id: str):
|
| 111 |
+
if repo_id in FLORENCE2_PROCESSOR_CANDIDATES:
|
| 112 |
+
return FLORENCE2_PROCESSOR_CANDIDATES[repo_id]
|
| 113 |
+
base = {"repo_id": repo_id, "trust_remote_code": True}
|
| 114 |
+
base.update(_revision_kwargs(repo_id))
|
| 115 |
+
return [base, {"repo_id": repo_id, "trust_remote_code": False}]
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def _processor_use_fast(processor_repo_id: str, requested_repo_id: str) -> bool:
|
| 119 |
+
if requested_repo_id == "thwri/CogFlorence-2.2-Large":
|
| 120 |
+
return True
|
| 121 |
+
return FLORENCE2_PROCESSOR_USE_FAST
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
|
| 125 |
+
@functools.lru_cache(maxsize=4)
|
| 126 |
+
def _ensure_florence2_runtime(device: str) -> Dict[str, Any]:
|
| 127 |
+
status: Dict[str, Any] = {
|
| 128 |
+
"device": device,
|
| 129 |
+
"flash_attn_2_available": False,
|
| 130 |
+
"install_attempted": False,
|
| 131 |
+
"install_succeeded": False,
|
| 132 |
+
"install_returncode": None,
|
| 133 |
+
}
|
| 134 |
+
if device != "cuda":
|
| 135 |
+
print("[Florence2 compat] runtime probe: non-cuda device")
|
| 136 |
+
else:
|
| 137 |
+
print("[Florence2 compat] runtime probe: flash-attn runtime install disabled")
|
| 138 |
+
return status
|
| 139 |
+
|
| 140 |
+
def _native_attn_kwargs(device: str) -> Tuple[Dict[str, Any], Dict[str, Any]]:
|
| 141 |
+
runtime = dict(_ensure_florence2_runtime(device))
|
| 142 |
+
runtime["attn_implementation"] = "default"
|
| 143 |
+
return {}, runtime
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
def _legacy_attn_kwargs(device: str) -> Tuple[Dict[str, Any], Dict[str, Any]]:
|
| 147 |
+
runtime = dict(_ensure_florence2_runtime(device))
|
| 148 |
+
requested = str(FLORENCE2_LEGACY_ATTN_IMPLEMENTATION).strip().lower() or "eager"
|
| 149 |
+
if requested != "eager":
|
| 150 |
+
print(f"[Florence2 compat] legacy attention request {requested} unsupported here, falling back to eager")
|
| 151 |
+
requested = "eager"
|
| 152 |
+
runtime["attn_implementation"] = requested
|
| 153 |
+
return {"attn_implementation": requested}, runtime
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
def _native_florence_module(model: Any) -> bool:
|
| 157 |
+
module = getattr(getattr(model, "__class__", None), "__module__", "") or ""
|
| 158 |
+
return module.startswith("transformers.models.florence2")
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
def _normalize_load_result(result: Any) -> Tuple[Any, Dict[str, Any]]:
|
| 162 |
+
if isinstance(result, tuple) and len(result) == 2 and isinstance(result[1], dict):
|
| 163 |
+
return result
|
| 164 |
+
return result, {}
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
def _safe_to_device(model: Any, device: str):
|
| 168 |
+
return model.eval().to(device)
|
| 169 |
+
|
| 170 |
+
|
| 171 |
+
def _load_processor(repo_id: str):
|
| 172 |
+
errors = []
|
| 173 |
+
for candidate in _processor_candidates(repo_id):
|
| 174 |
+
processor_repo_id = candidate["repo_id"]
|
| 175 |
+
trust_remote_code = bool(candidate.get("trust_remote_code", True))
|
| 176 |
+
revision = candidate.get("revision", None)
|
| 177 |
+
use_fast = _processor_use_fast(processor_repo_id, repo_id)
|
| 178 |
+
kwargs = {"use_fast": use_fast}
|
| 179 |
+
if revision:
|
| 180 |
+
kwargs["revision"] = revision
|
| 181 |
+
try:
|
| 182 |
+
processor = AutoProcessor.from_pretrained(
|
| 183 |
+
processor_repo_id,
|
| 184 |
+
trust_remote_code=trust_remote_code,
|
| 185 |
+
**kwargs,
|
| 186 |
+
)
|
| 187 |
+
mode = "trust_remote_code=True" if trust_remote_code else "native fallback"
|
| 188 |
+
print(
|
| 189 |
+
f"[Florence2 compat] processor={repo_id} source={processor_repo_id} "
|
| 190 |
+
f"mode={mode} revision={revision or 'main'} use_fast={use_fast}"
|
| 191 |
+
)
|
| 192 |
+
return processor
|
| 193 |
+
except Exception as e:
|
| 194 |
+
errors.append({
|
| 195 |
+
"source": processor_repo_id,
|
| 196 |
+
"trust_remote_code": trust_remote_code,
|
| 197 |
+
"revision": revision,
|
| 198 |
+
"error": repr(e),
|
| 199 |
+
})
|
| 200 |
+
raise RuntimeError(f"Failed to load processor for {repo_id}: {errors}")
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
def _load_native_model(repo_id: str, device: str):
|
| 204 |
+
if Florence2ForConditionalGeneration is None:
|
| 205 |
+
raise RuntimeError("Florence2ForConditionalGeneration is unavailable in this transformers build")
|
| 206 |
+
attn_kwargs, runtime = _native_attn_kwargs(device)
|
| 207 |
+
load_kwargs = dict(output_loading_info=True, **_dtype_kwargs(device), **attn_kwargs, **_revision_kwargs(repo_id))
|
| 208 |
+
model, loading_info = _normalize_load_result(
|
| 209 |
+
Florence2ForConditionalGeneration.from_pretrained(repo_id, **load_kwargs)
|
| 210 |
+
)
|
| 211 |
+
print(
|
| 212 |
+
f"[Florence2 compat] model={repo_id} loaded as native Florence2ForConditionalGeneration "
|
| 213 |
+
f"revision={FLORENCE2_REVISIONS.get(repo_id) or 'main'} attn={runtime.get('attn_implementation')}"
|
| 214 |
+
)
|
| 215 |
+
return model, loading_info, runtime
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
def _patch_generation_mixin(module: Any, label: str) -> bool:
|
| 219 |
+
if module is None or GenerationMixin is None:
|
| 220 |
+
return False
|
| 221 |
+
if hasattr(module, "generate") and callable(getattr(module, "generate")):
|
| 222 |
+
return False
|
| 223 |
+
|
| 224 |
+
cls = module.__class__
|
| 225 |
+
if issubclass(cls, GenerationMixin):
|
| 226 |
+
return False
|
| 227 |
+
|
| 228 |
+
if add_generation_mixin_to_remote_model is not None:
|
| 229 |
+
try:
|
| 230 |
+
patched_cls = add_generation_mixin_to_remote_model(cls)
|
| 231 |
+
if patched_cls is not cls:
|
| 232 |
+
module.__class__ = patched_cls
|
| 233 |
+
print(f"[Florence2 compat] patched {label} class with GenerationMixin: {patched_cls.__name__}")
|
| 234 |
+
return True
|
| 235 |
+
except Exception as e:
|
| 236 |
+
print(f"[Florence2 compat] official GenerationMixin patch failed for {label}: {e!r}")
|
| 237 |
+
|
| 238 |
+
patched_cls = type(f"{cls.__name__}WithGenerationMixin", (cls, GenerationMixin), {})
|
| 239 |
+
module.__class__ = patched_cls
|
| 240 |
+
print(f"[Florence2 compat] patched {label} class with GenerationMixin: {patched_cls.__name__}")
|
| 241 |
+
return True
|
| 242 |
+
|
| 243 |
+
|
| 244 |
+
def _first_non_none(*values):
|
| 245 |
+
for value in values:
|
| 246 |
+
if value is not None:
|
| 247 |
+
return value
|
| 248 |
+
return None
|
| 249 |
+
|
| 250 |
+
|
| 251 |
+
def _token_like_int(value: Any) -> Optional[int]:
|
| 252 |
+
if isinstance(value, bool):
|
| 253 |
+
return None
|
| 254 |
+
if isinstance(value, int):
|
| 255 |
+
return int(value)
|
| 256 |
+
return None
|
| 257 |
+
|
| 258 |
+
|
| 259 |
+
def _resolve_generation_ids(model: Any, processor: Any = None) -> Dict[str, Optional[int]]:
|
| 260 |
+
config = getattr(model, "config", None)
|
| 261 |
+
text_config = getattr(config, "text_config", None) if config is not None else None
|
| 262 |
+
tokenizer = getattr(processor, "tokenizer", None) if processor is not None else None
|
| 263 |
+
|
| 264 |
+
bos_token_id = _first_non_none(
|
| 265 |
+
_token_like_int(getattr(config, "bos_token_id", None)),
|
| 266 |
+
_token_like_int(getattr(text_config, "bos_token_id", None)),
|
| 267 |
+
_token_like_int(getattr(tokenizer, "bos_token_id", None)),
|
| 268 |
+
)
|
| 269 |
+
eos_token_id = _first_non_none(
|
| 270 |
+
_token_like_int(getattr(config, "eos_token_id", None)),
|
| 271 |
+
_token_like_int(getattr(text_config, "eos_token_id", None)),
|
| 272 |
+
_token_like_int(getattr(tokenizer, "eos_token_id", None)),
|
| 273 |
+
)
|
| 274 |
+
pad_token_id = _first_non_none(
|
| 275 |
+
_token_like_int(getattr(config, "pad_token_id", None)),
|
| 276 |
+
_token_like_int(getattr(text_config, "pad_token_id", None)),
|
| 277 |
+
_token_like_int(getattr(tokenizer, "pad_token_id", None)),
|
| 278 |
+
)
|
| 279 |
+
decoder_start_token_id = _first_non_none(
|
| 280 |
+
_token_like_int(getattr(config, "decoder_start_token_id", None)),
|
| 281 |
+
_token_like_int(getattr(text_config, "decoder_start_token_id", None)),
|
| 282 |
+
eos_token_id,
|
| 283 |
+
bos_token_id,
|
| 284 |
+
)
|
| 285 |
+
|
| 286 |
+
return {
|
| 287 |
+
"bos_token_id": bos_token_id,
|
| 288 |
+
"eos_token_id": eos_token_id,
|
| 289 |
+
"pad_token_id": pad_token_id,
|
| 290 |
+
"decoder_start_token_id": decoder_start_token_id,
|
| 291 |
+
}
|
| 292 |
+
|
| 293 |
+
|
| 294 |
+
def _apply_generation_ids(target: Any, ids: Dict[str, Optional[int]]) -> None:
|
| 295 |
+
if target is None:
|
| 296 |
+
return
|
| 297 |
+
for key, value in ids.items():
|
| 298 |
+
if value is None:
|
| 299 |
+
continue
|
| 300 |
+
try:
|
| 301 |
+
current = getattr(target, key, None)
|
| 302 |
+
except Exception:
|
| 303 |
+
current = None
|
| 304 |
+
if current is None:
|
| 305 |
+
try:
|
| 306 |
+
setattr(target, key, value)
|
| 307 |
+
except Exception:
|
| 308 |
+
pass
|
| 309 |
+
|
| 310 |
+
|
| 311 |
+
def _patch_prepare_inputs_for_generation(module: Any) -> bool:
|
| 312 |
+
if module is None or getattr(module, "_florence2_prepare_inputs_patched", False):
|
| 313 |
+
return False
|
| 314 |
+
original = getattr(module, "prepare_inputs_for_generation", None)
|
| 315 |
+
if not callable(original):
|
| 316 |
+
return False
|
| 317 |
+
|
| 318 |
+
def _wrapped_prepare_inputs_for_generation(self, decoder_input_ids, *args, **kwargs):
|
| 319 |
+
past_key_values = kwargs.get("past_key_values", None)
|
| 320 |
+
if past_key_values is not None:
|
| 321 |
+
reset_to_none = False
|
| 322 |
+
try:
|
| 323 |
+
first_layer = past_key_values[0]
|
| 324 |
+
first_k = first_layer[0] if first_layer is not None else None
|
| 325 |
+
if first_k is None:
|
| 326 |
+
reset_to_none = True
|
| 327 |
+
except Exception:
|
| 328 |
+
reset_to_none = True
|
| 329 |
+
if reset_to_none:
|
| 330 |
+
kwargs["past_key_values"] = None
|
| 331 |
+
return original(decoder_input_ids, *args, **kwargs)
|
| 332 |
+
|
| 333 |
+
module.prepare_inputs_for_generation = types.MethodType(_wrapped_prepare_inputs_for_generation, module)
|
| 334 |
+
module._florence2_prepare_inputs_patched = True
|
| 335 |
+
print("[Florence2 compat] patched legacy prepare_inputs_for_generation guard")
|
| 336 |
+
return True
|
| 337 |
+
|
| 338 |
+
|
| 339 |
+
def _safe_module_device_dtype(module: Any) -> Tuple[Optional[str], Optional[torch.dtype]]:
|
| 340 |
+
if module is None or not hasattr(module, "parameters"):
|
| 341 |
+
return None, None
|
| 342 |
+
try:
|
| 343 |
+
param = next(module.parameters())
|
| 344 |
+
return str(param.device), param.dtype
|
| 345 |
+
except Exception:
|
| 346 |
+
return None, None
|
| 347 |
+
|
| 348 |
+
|
| 349 |
+
|
| 350 |
+
def _beam_cap(default: int = 1) -> int:
|
| 351 |
+
raw = str(FLORENCE2_LEGACY_MAX_NUM_BEAMS if FLORENCE2_LEGACY_MAX_NUM_BEAMS is not None else default).strip()
|
| 352 |
+
try:
|
| 353 |
+
value = int(raw)
|
| 354 |
+
except Exception:
|
| 355 |
+
value = default
|
| 356 |
+
return max(0, value)
|
| 357 |
+
|
| 358 |
+
|
| 359 |
+
def _copy_generation_config(config: Any) -> Any:
|
| 360 |
+
if config is None:
|
| 361 |
+
return None
|
| 362 |
+
try:
|
| 363 |
+
return copy.deepcopy(config)
|
| 364 |
+
except Exception:
|
| 365 |
+
return config
|
| 366 |
+
|
| 367 |
+
|
| 368 |
+
def _prepare_generation_config_for_call(model: Any, language_model: Any, kwargs: Dict[str, Any], generation_ids: Dict[str, Optional[int]]) -> None:
|
| 369 |
+
active_generation_config = _copy_generation_config(getattr(model, "generation_config", None))
|
| 370 |
+
if active_generation_config is None and language_model is not None:
|
| 371 |
+
active_generation_config = _copy_generation_config(getattr(language_model, "generation_config", None))
|
| 372 |
+
if active_generation_config is None:
|
| 373 |
+
return
|
| 374 |
+
|
| 375 |
+
_apply_generation_ids(active_generation_config, generation_ids)
|
| 376 |
+
|
| 377 |
+
num_beams = kwargs.get("num_beams", getattr(active_generation_config, "num_beams", None))
|
| 378 |
+
try:
|
| 379 |
+
num_beams = int(num_beams) if num_beams is not None else None
|
| 380 |
+
except Exception:
|
| 381 |
+
num_beams = None
|
| 382 |
+
|
| 383 |
+
if num_beams is not None:
|
| 384 |
+
active_generation_config.num_beams = num_beams
|
| 385 |
+
|
| 386 |
+
if num_beams is None or num_beams <= 1:
|
| 387 |
+
try:
|
| 388 |
+
active_generation_config.early_stopping = False
|
| 389 |
+
except Exception:
|
| 390 |
+
pass
|
| 391 |
+
kwargs.pop("early_stopping", None)
|
| 392 |
+
|
| 393 |
+
kwargs.setdefault("generation_config", active_generation_config)
|
| 394 |
+
if language_model is not None:
|
| 395 |
+
try:
|
| 396 |
+
language_model.generation_config = active_generation_config
|
| 397 |
+
except Exception:
|
| 398 |
+
pass
|
| 399 |
+
|
| 400 |
+
|
| 401 |
+
def _patch_legacy_generate_bridge(model: Any, processor: Any = None) -> None:
|
| 402 |
+
language_model = getattr(model, "language_model", None)
|
| 403 |
+
patched_inner = _patch_generation_mixin(language_model, "language_model")
|
| 404 |
+
_patch_prepare_inputs_for_generation(language_model)
|
| 405 |
+
|
| 406 |
+
generation_ids = _resolve_generation_ids(model, processor)
|
| 407 |
+
_apply_generation_ids(getattr(model, "generation_config", None), generation_ids)
|
| 408 |
+
|
| 409 |
+
if language_model is not None:
|
| 410 |
+
try:
|
| 411 |
+
if hasattr(model, "generation_config"):
|
| 412 |
+
language_model.generation_config = model.generation_config
|
| 413 |
+
if hasattr(language_model, "generation_config"):
|
| 414 |
+
_apply_generation_ids(language_model.generation_config, generation_ids)
|
| 415 |
+
print("[Florence2 compat] bridged generation_config -> language_model.generation_config")
|
| 416 |
+
except Exception as e:
|
| 417 |
+
print(f"[Florence2 compat] failed to bridge generation_config: {e!r}")
|
| 418 |
+
|
| 419 |
+
if getattr(model, "_florence2_generate_bridge_patched", False):
|
| 420 |
+
return
|
| 421 |
+
|
| 422 |
+
original_generate = getattr(model, "generate", None)
|
| 423 |
+
if not callable(original_generate):
|
| 424 |
+
return
|
| 425 |
+
|
| 426 |
+
def _wrapped_generate(self, *args, **kwargs):
|
| 427 |
+
lm = getattr(self, "language_model", None)
|
| 428 |
+
if lm is not None and hasattr(self, "generation_config"):
|
| 429 |
+
try:
|
| 430 |
+
lm.generation_config = self.generation_config
|
| 431 |
+
except Exception:
|
| 432 |
+
pass
|
| 433 |
+
generation_ids = _resolve_generation_ids(self, processor)
|
| 434 |
+
_apply_generation_ids(getattr(self, "generation_config", None), generation_ids)
|
| 435 |
+
if lm is not None and hasattr(lm, "generation_config"):
|
| 436 |
+
_apply_generation_ids(lm.generation_config, generation_ids)
|
| 437 |
+
|
| 438 |
+
kwargs.setdefault("use_cache", FLORENCE2_LEGACY_USE_CACHE)
|
| 439 |
+
|
| 440 |
+
beam_cap = _beam_cap(default=1)
|
| 441 |
+
if beam_cap > 0:
|
| 442 |
+
requested_beams = kwargs.get("num_beams", None)
|
| 443 |
+
if requested_beams is None:
|
| 444 |
+
kwargs["num_beams"] = beam_cap
|
| 445 |
+
else:
|
| 446 |
+
try:
|
| 447 |
+
requested_beams_int = int(requested_beams)
|
| 448 |
+
except Exception:
|
| 449 |
+
requested_beams_int = requested_beams
|
| 450 |
+
if isinstance(requested_beams_int, int) and requested_beams_int > beam_cap:
|
| 451 |
+
print(
|
| 452 |
+
f"[Florence2 compat] clamped legacy num_beams from {requested_beams_int} to {beam_cap}"
|
| 453 |
+
)
|
| 454 |
+
kwargs["num_beams"] = beam_cap
|
| 455 |
+
|
| 456 |
+
for key, value in generation_ids.items():
|
| 457 |
+
if value is not None:
|
| 458 |
+
kwargs.setdefault(key, value)
|
| 459 |
+
|
| 460 |
+
_prepare_generation_config_for_call(self, lm, kwargs, generation_ids)
|
| 461 |
+
|
| 462 |
+
_condensed_generate_log(self, kwargs)
|
| 463 |
+
return original_generate(*args, **kwargs)
|
| 464 |
+
|
| 465 |
+
model.generate = types.MethodType(_wrapped_generate, model)
|
| 466 |
+
model._florence2_generate_bridge_patched = True
|
| 467 |
+
print("[Florence2 compat] legacy generate defaults: " + ", ".join(f"{k}={v}" for k, v in generation_ids.items()))
|
| 468 |
+
if patched_inner:
|
| 469 |
+
print("[Florence2 compat] patched legacy Florence generate bridge")
|
| 470 |
+
|
| 471 |
+
|
| 472 |
+
def _load_legacy_model(repo_id: str, device: str, processor: Any = None):
|
| 473 |
+
if AutoModelForCausalLM is None:
|
| 474 |
+
raise RuntimeError("AutoModelForCausalLM is unavailable in this transformers build")
|
| 475 |
+
attn_kwargs, runtime = _legacy_attn_kwargs(device)
|
| 476 |
+
load_kwargs = dict(output_loading_info=True, **_dtype_kwargs(device), **attn_kwargs, **_revision_kwargs(repo_id))
|
| 477 |
+
try:
|
| 478 |
+
model, loading_info = _normalize_load_result(
|
| 479 |
+
AutoModelForCausalLM.from_pretrained(repo_id, trust_remote_code=True, **load_kwargs)
|
| 480 |
+
)
|
| 481 |
+
except TypeError:
|
| 482 |
+
load_kwargs.pop("attn_implementation", None)
|
| 483 |
+
runtime["attn_implementation"] = "legacy_default"
|
| 484 |
+
model, loading_info = _normalize_load_result(
|
| 485 |
+
AutoModelForCausalLM.from_pretrained(repo_id, trust_remote_code=True, **load_kwargs)
|
| 486 |
+
)
|
| 487 |
+
_patch_legacy_generate_bridge(model, processor=processor)
|
| 488 |
+
print(
|
| 489 |
+
f"[Florence2 compat] model={repo_id} loaded via AutoModelForCausalLM + trust_remote_code=True "
|
| 490 |
+
f"revision={FLORENCE2_REVISIONS.get(repo_id) or 'main'} attn={runtime.get('attn_implementation')}"
|
| 491 |
+
)
|
| 492 |
+
return model, loading_info, runtime
|
| 493 |
+
|
| 494 |
+
|
| 495 |
+
def _ensure_image_token(processor: Any, model: Any) -> None:
|
| 496 |
+
tokenizer = getattr(processor, "tokenizer", None)
|
| 497 |
+
config = getattr(model, "config", None)
|
| 498 |
+
if tokenizer is None or config is None:
|
| 499 |
+
return
|
| 500 |
+
|
| 501 |
+
tokenizer.image_token = getattr(tokenizer, "image_token", None) or _IMAGE_TOKEN
|
| 502 |
+
|
| 503 |
+
token_id = tokenizer.convert_tokens_to_ids(tokenizer.image_token)
|
| 504 |
+
needs_add = token_id is None
|
| 505 |
+
if token_id is not None:
|
| 506 |
+
unk_id = getattr(tokenizer, "unk_token_id", None)
|
| 507 |
+
if unk_id is not None and token_id == unk_id:
|
| 508 |
+
pieces = tokenizer.encode(tokenizer.image_token, add_special_tokens=False)
|
| 509 |
+
needs_add = len(pieces) != 1 or pieces[0] == unk_id
|
| 510 |
+
|
| 511 |
+
added = 0
|
| 512 |
+
if needs_add:
|
| 513 |
+
added = tokenizer.add_tokens(
|
| 514 |
+
AddedToken(tokenizer.image_token, special=True, normalized=False),
|
| 515 |
+
special_tokens=True,
|
| 516 |
+
)
|
| 517 |
+
print(f"[Florence2 compat] added special image token to tokenizer: added={added}")
|
| 518 |
+
|
| 519 |
+
pieces = tokenizer.encode(tokenizer.image_token, add_special_tokens=False)
|
| 520 |
+
if len(pieces) == 1:
|
| 521 |
+
image_token_id = int(pieces[0])
|
| 522 |
+
tokenizer.image_token_id = image_token_id
|
| 523 |
+
if getattr(config, "image_token_id", None) != image_token_id:
|
| 524 |
+
config.image_token_id = image_token_id
|
| 525 |
+
print(f"[Florence2 compat] model.config.image_token_id set to {image_token_id}")
|
| 526 |
+
|
| 527 |
+
if added > 0 and hasattr(model, "resize_token_embeddings"):
|
| 528 |
+
try:
|
| 529 |
+
model.resize_token_embeddings(len(tokenizer), pad_to_multiple_of=64)
|
| 530 |
+
except TypeError:
|
| 531 |
+
try:
|
| 532 |
+
model.resize_token_embeddings(len(tokenizer), 64)
|
| 533 |
+
except TypeError:
|
| 534 |
+
model.resize_token_embeddings(len(tokenizer))
|
| 535 |
+
print(f"[Florence2 compat] resize_token_embeddings({len(tokenizer)}) applied")
|
| 536 |
+
|
| 537 |
+
|
| 538 |
+
def audit_loading_info(repo_id: str, loading_info: Dict[str, Any]) -> Dict[str, Any]:
|
| 539 |
+
missing = list(loading_info.get("missing_keys") or [])
|
| 540 |
+
unexpected = list(loading_info.get("unexpected_keys") or [])
|
| 541 |
+
|
| 542 |
+
critical_patterns = (
|
| 543 |
+
"lm_head.weight",
|
| 544 |
+
"model.language_model.decoder.",
|
| 545 |
+
"model.multi_modal_projector.",
|
| 546 |
+
)
|
| 547 |
+
legacy_patterns = (
|
| 548 |
+
"language_model.model.",
|
| 549 |
+
"language_model.lm_head.weight",
|
| 550 |
+
"image_projection",
|
| 551 |
+
"image_proj_norm.",
|
| 552 |
+
"image_pos_embed.",
|
| 553 |
+
"visual_temporal_embed.",
|
| 554 |
+
"vision_tower.",
|
| 555 |
+
)
|
| 556 |
+
|
| 557 |
+
critical_missing = [k for k in missing if any(p in k for p in critical_patterns)]
|
| 558 |
+
legacy_unexpected = [k for k in unexpected if any(p in k for p in legacy_patterns)]
|
| 559 |
+
suspicious = bool(critical_missing and legacy_unexpected)
|
| 560 |
+
|
| 561 |
+
if suspicious:
|
| 562 |
+
print(
|
| 563 |
+
f"[Florence2 compat] suspicious native load mismatch for {repo_id}: "
|
| 564 |
+
f"critical_missing={len(critical_missing)} legacy_unexpected={len(legacy_unexpected)}"
|
| 565 |
+
)
|
| 566 |
+
print("[Florence2 compat] trying legacy->native key conversion fallback")
|
| 567 |
+
|
| 568 |
+
return {
|
| 569 |
+
"missing_keys": missing,
|
| 570 |
+
"unexpected_keys": unexpected,
|
| 571 |
+
"missing_count": len(missing),
|
| 572 |
+
"unexpected_count": len(unexpected),
|
| 573 |
+
"critical_missing_count": len(critical_missing),
|
| 574 |
+
"legacy_unexpected_count": len(legacy_unexpected),
|
| 575 |
+
"suspicious_mismatch": suspicious,
|
| 576 |
+
}
|
| 577 |
+
|
| 578 |
+
|
| 579 |
+
def _collect_weight_files(snapshot_dir: str) -> Iterable[str]:
|
| 580 |
+
candidates = []
|
| 581 |
+
for index_name in ("model.safetensors.index.json", "pytorch_model.bin.index.json"):
|
| 582 |
+
index_path = os.path.join(snapshot_dir, index_name)
|
| 583 |
+
if os.path.exists(index_path):
|
| 584 |
+
with open(index_path, "r", encoding="utf-8") as f:
|
| 585 |
+
index_data = json.load(f)
|
| 586 |
+
weight_map = index_data.get("weight_map") or {}
|
| 587 |
+
seen = set()
|
| 588 |
+
for rel_path in weight_map.values():
|
| 589 |
+
if rel_path not in seen:
|
| 590 |
+
candidates.append(os.path.join(snapshot_dir, rel_path))
|
| 591 |
+
seen.add(rel_path)
|
| 592 |
+
return candidates
|
| 593 |
+
|
| 594 |
+
for file_name in (
|
| 595 |
+
"model.safetensors",
|
| 596 |
+
"pytorch_model.bin",
|
| 597 |
+
"pytorch_model.pt",
|
| 598 |
+
):
|
| 599 |
+
path = os.path.join(snapshot_dir, file_name)
|
| 600 |
+
if os.path.exists(path):
|
| 601 |
+
return [path]
|
| 602 |
+
|
| 603 |
+
for name in sorted(os.listdir(snapshot_dir)):
|
| 604 |
+
if name.endswith(".safetensors") or name.endswith(".bin"):
|
| 605 |
+
candidates.append(os.path.join(snapshot_dir, name))
|
| 606 |
+
return candidates
|
| 607 |
+
|
| 608 |
+
|
| 609 |
+
def _load_state_dict_from_snapshot(repo_id: str) -> Dict[str, torch.Tensor]:
|
| 610 |
+
if snapshot_download is None:
|
| 611 |
+
raise RuntimeError("huggingface_hub.snapshot_download is unavailable")
|
| 612 |
+
|
| 613 |
+
snapshot_dir = snapshot_download(
|
| 614 |
+
repo_id,
|
| 615 |
+
revision=FLORENCE2_REVISIONS.get(repo_id),
|
| 616 |
+
allow_patterns=[
|
| 617 |
+
"*.safetensors",
|
| 618 |
+
"*.safetensors.index.json",
|
| 619 |
+
"*.bin",
|
| 620 |
+
"*.bin.index.json",
|
| 621 |
+
"config.json",
|
| 622 |
+
"generation_config.json",
|
| 623 |
+
],
|
| 624 |
+
ignore_patterns=["*.msgpack", "*.h5", "*.ot", "*.onnx", "*.tflite"],
|
| 625 |
+
)
|
| 626 |
+
|
| 627 |
+
state_dict: Dict[str, torch.Tensor] = {}
|
| 628 |
+
weight_files = list(_collect_weight_files(snapshot_dir))
|
| 629 |
+
if not weight_files:
|
| 630 |
+
raise RuntimeError(f"No model weight files found in snapshot for {repo_id}")
|
| 631 |
+
|
| 632 |
+
for path in weight_files:
|
| 633 |
+
if path.endswith(".safetensors"):
|
| 634 |
+
if load_safetensors_file is None:
|
| 635 |
+
raise RuntimeError("safetensors is unavailable but checkpoint uses safetensors")
|
| 636 |
+
shard = load_safetensors_file(path, device="cpu")
|
| 637 |
+
else:
|
| 638 |
+
shard = torch.load(path, map_location="cpu")
|
| 639 |
+
if isinstance(shard, dict) and "state_dict" in shard and isinstance(shard["state_dict"], dict):
|
| 640 |
+
shard = shard["state_dict"]
|
| 641 |
+
state_dict.update(shard)
|
| 642 |
+
|
| 643 |
+
print(f"[Florence2 compat] loaded raw state_dict from snapshot: files={len(weight_files)} tensors={len(state_dict)}")
|
| 644 |
+
return state_dict
|
| 645 |
+
|
| 646 |
+
|
| 647 |
+
def _rename_vision_tower_key(key: str) -> str:
|
| 648 |
+
new_key = f"model.{key}"
|
| 649 |
+
new_key = new_key.replace(".convs.", ".convs.")
|
| 650 |
+
new_key = new_key.replace(".proj.", ".conv.") if ".convs." in new_key else new_key
|
| 651 |
+
|
| 652 |
+
replacements = (
|
| 653 |
+
(".spatial_block.conv1.fn.dw.", ".spatial_block.conv1."),
|
| 654 |
+
(".spatial_block.window_attn.norm.", ".spatial_block.norm1."),
|
| 655 |
+
(".spatial_block.window_attn.fn.", ".spatial_block.window_attn."),
|
| 656 |
+
(".spatial_block.ffn.norm.", ".spatial_block.norm2."),
|
| 657 |
+
(".spatial_block.ffn.fn.net.", ".spatial_block.ffn."),
|
| 658 |
+
(".channel_block.conv1.fn.dw.", ".channel_block.conv1."),
|
| 659 |
+
(".channel_block.channel_attn.norm.", ".channel_block.norm1."),
|
| 660 |
+
(".channel_block.channel_attn.fn.", ".channel_block.channel_attn."),
|
| 661 |
+
(".channel_block.conv2.fn.dw.", ".channel_block.conv2."),
|
| 662 |
+
(".channel_block.ffn.norm.", ".channel_block.norm2."),
|
| 663 |
+
(".channel_block.ffn.fn.net.", ".channel_block.ffn."),
|
| 664 |
+
)
|
| 665 |
+
for src, dst in replacements:
|
| 666 |
+
if src in new_key:
|
| 667 |
+
new_key = new_key.replace(src, dst)
|
| 668 |
+
return new_key
|
| 669 |
+
|
| 670 |
+
|
| 671 |
+
def convert_legacy_state_dict_to_native(state_dict: Dict[str, torch.Tensor]) -> Dict[str, torch.Tensor]:
|
| 672 |
+
converted: Dict[str, torch.Tensor] = {}
|
| 673 |
+
|
| 674 |
+
direct_map = {
|
| 675 |
+
"image_proj_norm.weight": "model.multi_modal_projector.image_proj_norm.weight",
|
| 676 |
+
"image_proj_norm.bias": "model.multi_modal_projector.image_proj_norm.bias",
|
| 677 |
+
"image_pos_embed.row_embeddings.weight": "model.multi_modal_projector.image_position_embed.row_embeddings.weight",
|
| 678 |
+
"image_pos_embed.column_embeddings.weight": "model.multi_modal_projector.image_position_embed.column_embeddings.weight",
|
| 679 |
+
"visual_temporal_embed.pos_idx_to_embed": "model.multi_modal_projector.visual_temporal_embed.pos_idx_to_embed",
|
| 680 |
+
"language_model.lm_head.weight": "lm_head.weight",
|
| 681 |
+
}
|
| 682 |
+
|
| 683 |
+
for key, value in state_dict.items():
|
| 684 |
+
tensor = value
|
| 685 |
+
new_key = key
|
| 686 |
+
|
| 687 |
+
if key in direct_map:
|
| 688 |
+
new_key = direct_map[key]
|
| 689 |
+
elif key == "image_projection":
|
| 690 |
+
new_key = "model.multi_modal_projector.image_projection.weight"
|
| 691 |
+
tensor = value.transpose(1, 0).contiguous()
|
| 692 |
+
elif key.startswith("language_model.model."):
|
| 693 |
+
new_key = key.replace("language_model.model.", "model.language_model.", 1)
|
| 694 |
+
elif key.startswith("vision_tower."):
|
| 695 |
+
new_key = _rename_vision_tower_key(key)
|
| 696 |
+
elif key.startswith("model.") or key == "lm_head.weight":
|
| 697 |
+
new_key = key
|
| 698 |
+
else:
|
| 699 |
+
# Keep unknown keys as-is; they will appear in audit logs if unused.
|
| 700 |
+
new_key = key
|
| 701 |
+
|
| 702 |
+
converted[new_key] = tensor
|
| 703 |
+
|
| 704 |
+
print(
|
| 705 |
+
"[Florence2 compat] converted legacy state_dict to native-style keys: "
|
| 706 |
+
f"input={len(state_dict)} output={len(converted)}"
|
| 707 |
+
)
|
| 708 |
+
return converted
|
| 709 |
+
|
| 710 |
+
|
| 711 |
+
def _rebuild_native_model_from_converted_state(base_model: Any, processor: Any, repo_id: str):
|
| 712 |
+
state_dict = _load_state_dict_from_snapshot(repo_id)
|
| 713 |
+
converted_state = convert_legacy_state_dict_to_native(state_dict)
|
| 714 |
+
|
| 715 |
+
native_cls = Florence2ForConditionalGeneration or type(base_model)
|
| 716 |
+
converted_model = native_cls(base_model.config)
|
| 717 |
+
incompatible = converted_model.load_state_dict(converted_state, strict=False)
|
| 718 |
+
if hasattr(converted_model, "tie_weights"):
|
| 719 |
+
converted_model.tie_weights()
|
| 720 |
+
|
| 721 |
+
loading_info = {
|
| 722 |
+
"missing_keys": list(getattr(incompatible, "missing_keys", []) or []),
|
| 723 |
+
"unexpected_keys": list(getattr(incompatible, "unexpected_keys", []) or []),
|
| 724 |
+
}
|
| 725 |
+
_ensure_image_token(processor, converted_model)
|
| 726 |
+
audit = audit_loading_info(repo_id, loading_info)
|
| 727 |
+
audit["converted_from_legacy"] = True
|
| 728 |
+
return converted_model, audit
|
| 729 |
+
|
| 730 |
+
|
| 731 |
+
def _boolish(value: Any) -> Optional[bool]:
|
| 732 |
+
if isinstance(value, bool):
|
| 733 |
+
return value
|
| 734 |
+
return None
|
| 735 |
+
|
| 736 |
+
|
| 737 |
+
def _effective_generate_settings(model: Any, kwargs: Dict[str, Any]) -> Dict[str, Any]:
|
| 738 |
+
generation_config = kwargs.get("generation_config", getattr(model, "generation_config", None))
|
| 739 |
+
use_cache = kwargs.get("use_cache", getattr(generation_config, "use_cache", None))
|
| 740 |
+
num_beams = kwargs.get("num_beams", getattr(generation_config, "num_beams", None))
|
| 741 |
+
early_stopping = kwargs.get("early_stopping", getattr(generation_config, "early_stopping", None))
|
| 742 |
+
max_new_tokens = kwargs.get("max_new_tokens", getattr(generation_config, "max_new_tokens", None))
|
| 743 |
+
return {
|
| 744 |
+
"use_cache": use_cache,
|
| 745 |
+
"num_beams": num_beams,
|
| 746 |
+
"early_stopping": early_stopping,
|
| 747 |
+
"max_new_tokens": max_new_tokens,
|
| 748 |
+
}
|
| 749 |
+
|
| 750 |
+
|
| 751 |
+
def _condensed_generate_log(model: Any, kwargs: Dict[str, Any]) -> None:
|
| 752 |
+
settings = _effective_generate_settings(model, kwargs)
|
| 753 |
+
loader = getattr(model, "_florence2_loader", "unknown")
|
| 754 |
+
attn = getattr(model, "_florence2_attn_impl", "unknown")
|
| 755 |
+
vision_device, vision_dtype = _safe_module_device_dtype(getattr(model, "vision_tower", None))
|
| 756 |
+
language_device, language_dtype = _safe_module_device_dtype(getattr(model, "language_model", None))
|
| 757 |
+
print(
|
| 758 |
+
"[Florence2 compat] call "
|
| 759 |
+
f"loader={loader} attn={attn} "
|
| 760 |
+
f"vt={vision_device}/{vision_dtype} lm={language_device}/{language_dtype} "
|
| 761 |
+
f"cache={settings['use_cache']} beams={settings['num_beams']} "
|
| 762 |
+
f"early={settings['early_stopping']} max_new_tokens={settings['max_new_tokens']} "
|
| 763 |
+
f"repo={getattr(model, '_florence2_repo_id', None)}"
|
| 764 |
+
)
|
| 765 |
+
|
| 766 |
+
|
| 767 |
+
def _default_max_new_tokens(model: Any) -> int:
|
| 768 |
+
repo_id = getattr(model, "_florence2_repo_id", None)
|
| 769 |
+
if isinstance(repo_id, str) and repo_id in FLORENCE2_GENERATE_MAX_NEW_TOKENS_BY_REPO:
|
| 770 |
+
return int(FLORENCE2_GENERATE_MAX_NEW_TOKENS_BY_REPO[repo_id])
|
| 771 |
+
return int(FLORENCE2_GENERATE_DEFAULT_MAX_NEW_TOKENS)
|
| 772 |
+
|
| 773 |
+
|
| 774 |
+
def _autocast_context(model: Any):
|
| 775 |
+
device, dtype = _infer_tensor_runtime(model, "cpu")
|
| 776 |
+
if not str(device).startswith("cuda"):
|
| 777 |
+
return torch.autocast(device_type="cpu", enabled=False)
|
| 778 |
+
target_dtype = dtype if dtype in (torch.float16, torch.bfloat16) else torch.float16
|
| 779 |
+
return torch.autocast(device_type="cuda", dtype=target_dtype)
|
| 780 |
+
|
| 781 |
+
|
| 782 |
+
def generate_florence2(model: Any, **kwargs):
|
| 783 |
+
kwargs.setdefault("max_new_tokens", _default_max_new_tokens(model))
|
| 784 |
+
kwargs.setdefault("num_beams", FLORENCE2_GENERATE_DEFAULT_NUM_BEAMS)
|
| 785 |
+
if isinstance(kwargs.get("num_beams"), int) and kwargs["num_beams"] <= 1:
|
| 786 |
+
kwargs.pop("early_stopping", None)
|
| 787 |
+
_condensed_generate_log(model, kwargs)
|
| 788 |
+
with torch.inference_mode():
|
| 789 |
+
with _autocast_context(model):
|
| 790 |
+
return model.generate(**kwargs)
|
| 791 |
+
|
| 792 |
+
|
| 793 |
+
def load_florence2_bundle(repo_id: str, device: str, prefer_native_on_v5: bool = True):
|
| 794 |
+
major = _major_version()
|
| 795 |
+
processor = _load_processor(repo_id)
|
| 796 |
+
|
| 797 |
+
if major < 5 or not prefer_native_on_v5 or Florence2ForConditionalGeneration is None:
|
| 798 |
+
model, loading_info, runtime = _load_legacy_model(repo_id, device=device, processor=processor)
|
| 799 |
+
model = _safe_to_device(model, device)
|
| 800 |
+
audit = audit_loading_info(repo_id, loading_info)
|
| 801 |
+
audit["loader"] = "legacy_remote_code"
|
| 802 |
+
audit["runtime"] = runtime
|
| 803 |
+
model._florence2_loader = audit["loader"]
|
| 804 |
+
model._florence2_attn_impl = runtime.get("attn_implementation")
|
| 805 |
+
model._florence2_repo_id = repo_id
|
| 806 |
+
return model, processor, audit
|
| 807 |
+
|
| 808 |
+
model, loading_info, runtime = _load_native_model(repo_id, device=device)
|
| 809 |
+
audit = audit_loading_info(repo_id, loading_info)
|
| 810 |
+
audit["loader"] = "native"
|
| 811 |
+
audit["runtime"] = runtime
|
| 812 |
+
|
| 813 |
+
if audit.get("suspicious_mismatch"):
|
| 814 |
+
try:
|
| 815 |
+
converted_model, converted_audit = _rebuild_native_model_from_converted_state(model, processor, repo_id)
|
| 816 |
+
del model
|
| 817 |
+
gc.collect()
|
| 818 |
+
model = converted_model
|
| 819 |
+
audit = converted_audit
|
| 820 |
+
audit["loader"] = "converted_native"
|
| 821 |
+
audit["runtime"] = runtime
|
| 822 |
+
except Exception as e:
|
| 823 |
+
audit["conversion_error"] = repr(e)
|
| 824 |
+
print(f"[Florence2 compat] legacy->native conversion fallback failed for {repo_id}: {e!r}")
|
| 825 |
+
|
| 826 |
+
if _native_florence_module(model):
|
| 827 |
+
_ensure_image_token(processor, model)
|
| 828 |
+
|
| 829 |
+
model = _safe_to_device(model, device)
|
| 830 |
+
model._florence2_loader = audit.get("loader", "unknown")
|
| 831 |
+
model._florence2_attn_impl = runtime.get("attn_implementation")
|
| 832 |
+
model._florence2_repo_id = repo_id
|
| 833 |
+
return model, processor, audit
|
| 834 |
+
|
| 835 |
+
|
| 836 |
+
def _candidate_image_seq_length(processor: Any, model: Any) -> Optional[int]:
|
| 837 |
+
candidates = (
|
| 838 |
+
getattr(getattr(model, "config", None), "image_seq_length", None),
|
| 839 |
+
getattr(processor, "num_image_tokens", None),
|
| 840 |
+
getattr(processor, "image_seq_length", None),
|
| 841 |
+
getattr(getattr(processor, "image_processor", None), "image_seq_length", None),
|
| 842 |
+
)
|
| 843 |
+
for value in candidates:
|
| 844 |
+
if isinstance(value, int) and value > 0:
|
| 845 |
+
return value
|
| 846 |
+
return None
|
| 847 |
+
|
| 848 |
+
|
| 849 |
+
def _infer_tensor_runtime(model: Any, fallback_device: str) -> Tuple[str, Optional[torch.dtype]]:
|
| 850 |
+
modules = [
|
| 851 |
+
getattr(model, "vision_tower", None),
|
| 852 |
+
getattr(getattr(model, "model", None), "vision_tower", None),
|
| 853 |
+
model,
|
| 854 |
+
]
|
| 855 |
+
for module in modules:
|
| 856 |
+
if module is None or not hasattr(module, "parameters"):
|
| 857 |
+
continue
|
| 858 |
+
try:
|
| 859 |
+
param = next(module.parameters())
|
| 860 |
+
return str(param.device), param.dtype
|
| 861 |
+
except StopIteration:
|
| 862 |
+
continue
|
| 863 |
+
except Exception:
|
| 864 |
+
continue
|
| 865 |
+
return fallback_device, getattr(model, "dtype", None)
|
| 866 |
+
|
| 867 |
+
|
| 868 |
+
|
| 869 |
+
def prepare_florence2_inputs(processor: Any, model: Any, prompt: str, image: Any, device: str):
|
| 870 |
+
inputs = processor(text=prompt, images=image, return_tensors="pt")
|
| 871 |
+
|
| 872 |
+
if _native_florence_module(model):
|
| 873 |
+
input_ids = inputs.get("input_ids")
|
| 874 |
+
pixel_values = inputs.get("pixel_values")
|
| 875 |
+
image_token_id = getattr(getattr(model, "config", None), "image_token_id", None)
|
| 876 |
+
image_seq_length = _candidate_image_seq_length(processor, model)
|
| 877 |
+
|
| 878 |
+
if input_ids is not None and pixel_values is not None and image_token_id is not None and image_seq_length:
|
| 879 |
+
n_image_tokens = int((input_ids == image_token_id).sum().item())
|
| 880 |
+
if n_image_tokens == 0:
|
| 881 |
+
batch_size = input_ids.shape[0]
|
| 882 |
+
prefix = torch.full(
|
| 883 |
+
(batch_size, int(image_seq_length)),
|
| 884 |
+
int(image_token_id),
|
| 885 |
+
dtype=input_ids.dtype,
|
| 886 |
+
device=input_ids.device,
|
| 887 |
+
)
|
| 888 |
+
inputs["input_ids"] = torch.cat([prefix, input_ids], dim=1)
|
| 889 |
+
|
| 890 |
+
attention_mask = inputs.get("attention_mask")
|
| 891 |
+
if attention_mask is not None:
|
| 892 |
+
prefix_mask = torch.ones(
|
| 893 |
+
(batch_size, int(image_seq_length)),
|
| 894 |
+
dtype=attention_mask.dtype,
|
| 895 |
+
device=attention_mask.device,
|
| 896 |
+
)
|
| 897 |
+
inputs["attention_mask"] = torch.cat([prefix_mask, attention_mask], dim=1)
|
| 898 |
+
|
| 899 |
+
print(
|
| 900 |
+
f"[Florence2 compat] injected {int(image_seq_length)} image placeholder tokens for native Florence-2"
|
| 901 |
+
)
|
| 902 |
+
|
| 903 |
+
target_device, float_dtype = _infer_tensor_runtime(model, device)
|
| 904 |
+
prepared = {}
|
| 905 |
+
for k, v in inputs.items():
|
| 906 |
+
if not hasattr(v, "to"):
|
| 907 |
+
prepared[k] = v
|
| 908 |
+
continue
|
| 909 |
+
if isinstance(v, torch.Tensor) and torch.is_floating_point(v):
|
| 910 |
+
prepared[k] = v.to(device=target_device, dtype=float_dtype or v.dtype)
|
| 911 |
+
else:
|
| 912 |
+
prepared[k] = v.to(device=target_device)
|
| 913 |
+
|
| 914 |
+
pv = prepared.get("pixel_values")
|
| 915 |
+
if isinstance(pv, torch.Tensor):
|
| 916 |
+
print(
|
| 917 |
+
"[Florence2 compat] prepared pixel_values "
|
| 918 |
+
f"device={pv.device} dtype={pv.dtype} target_float_dtype={float_dtype} native={_native_florence_module(model)}"
|
| 919 |
+
)
|
| 920 |
+
|
| 921 |
+
return prepared
|
| 922 |
+
|
| 923 |
+
|
| 924 |
+
def safe_load_florence2_bundle(repo_id: str, device: str, prefer_native_on_v5: bool = True):
|
| 925 |
+
return load_florence2_bundle(repo_id=repo_id, device=device, prefer_native_on_v5=prefer_native_on_v5)
|
tagger/tagger.py
CHANGED
|
@@ -8,13 +8,14 @@ from pathlib import Path
|
|
| 8 |
|
| 9 |
WD_MODEL_NAMES = ["p1atdev/wd-swinv2-tagger-v3-hf"]
|
| 10 |
WD_MODEL_NAME = WD_MODEL_NAMES[0]
|
|
|
|
| 11 |
|
| 12 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 13 |
default_device = device
|
| 14 |
|
| 15 |
try:
|
| 16 |
-
wd_model = AutoModelForImageClassification.from_pretrained(WD_MODEL_NAME, trust_remote_code=True).to(default_device).eval()
|
| 17 |
-
wd_processor = AutoImageProcessor.from_pretrained(WD_MODEL_NAME, trust_remote_code=True)
|
| 18 |
except Exception as e:
|
| 19 |
print(e)
|
| 20 |
wd_model = wd_processor = None
|
|
|
|
| 8 |
|
| 9 |
WD_MODEL_NAMES = ["p1atdev/wd-swinv2-tagger-v3-hf"]
|
| 10 |
WD_MODEL_NAME = WD_MODEL_NAMES[0]
|
| 11 |
+
WD_MODEL_REVISION = "b09fdef"
|
| 12 |
|
| 13 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 14 |
default_device = device
|
| 15 |
|
| 16 |
try:
|
| 17 |
+
wd_model = AutoModelForImageClassification.from_pretrained(WD_MODEL_NAME, trust_remote_code=True, revision=WD_MODEL_REVISION, code_revision=WD_MODEL_REVISION).to(default_device).eval()
|
| 18 |
+
wd_processor = AutoImageProcessor.from_pretrained(WD_MODEL_NAME, trust_remote_code=True, revision=WD_MODEL_REVISION, code_revision=WD_MODEL_REVISION)
|
| 19 |
except Exception as e:
|
| 20 |
print(e)
|
| 21 |
wd_model = wd_processor = None
|
utils.py
CHANGED
|
@@ -275,11 +275,11 @@ def civ_redirect_down(url, dir_, civitai_api_key, romanize, alternative_name):
|
|
| 275 |
elif os.path.exists(os.path.join(dir_, filename_base)):
|
| 276 |
return os.path.join(dir_, filename_base), filename_base
|
| 277 |
|
| 278 |
-
|
| 279 |
-
f'
|
| 280 |
-
f'-
|
| 281 |
)
|
| 282 |
-
r_code = os.system(
|
| 283 |
|
| 284 |
# if r_code != 0:
|
| 285 |
# raise RuntimeError(f"Failed to download file: {filename_base}. Error code: {r_code}")
|
|
@@ -293,27 +293,32 @@ def civ_redirect_down(url, dir_, civitai_api_key, romanize, alternative_name):
|
|
| 293 |
|
| 294 |
def civ_api_down(url, dir_, civitai_api_key, civ_filename):
|
| 295 |
"""
|
| 296 |
-
This method is susceptible to being blocked because it generates a lot of temp redirect links with
|
| 297 |
-
If an API key limit is reached, generating a new API key and using it can fix the issue.
|
| 298 |
"""
|
| 299 |
output_path = None
|
| 300 |
-
|
| 301 |
url_dl = url + f"?token={civitai_api_key}"
|
|
|
|
| 302 |
if not civ_filename:
|
| 303 |
-
|
| 304 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
else:
|
| 306 |
output_path = os.path.join(dir_, civ_filename)
|
|
|
|
| 307 |
if not os.path.exists(output_path):
|
| 308 |
-
|
| 309 |
-
f'
|
| 310 |
-
f'-
|
| 311 |
)
|
| 312 |
-
os.system(
|
| 313 |
-
|
| 314 |
return output_path
|
| 315 |
|
| 316 |
-
|
| 317 |
def drive_down(url, dir_):
|
| 318 |
import gdown
|
| 319 |
|
|
@@ -354,10 +359,16 @@ def hf_down(url, dir_, hf_token, romanize):
|
|
| 354 |
url = url.replace("/blob/", "/resolve/")
|
| 355 |
|
| 356 |
if hf_token:
|
| 357 |
-
|
| 358 |
-
|
|
|
|
|
|
|
|
|
|
| 359 |
else:
|
| 360 |
-
os.system(
|
|
|
|
|
|
|
|
|
|
| 361 |
|
| 362 |
return output_path
|
| 363 |
|
|
@@ -370,7 +381,8 @@ def download_things(directory, url, hf_token="", civitai_api_key="", romanize=Fa
|
|
| 370 |
downloaded_file_path = drive_down(url, directory)
|
| 371 |
elif "huggingface.co" in url:
|
| 372 |
downloaded_file_path = hf_down(url, directory, hf_token, romanize)
|
| 373 |
-
elif "civitai.
|
|
|
|
| 374 |
if not civitai_api_key:
|
| 375 |
msg = "You need an API key to download Civitai models."
|
| 376 |
print(f"\033[91m{msg}\033[0m")
|
|
@@ -393,7 +405,10 @@ def download_things(directory, url, hf_token="", civitai_api_key="", romanize=Fa
|
|
| 393 |
gr.Warning(msg)
|
| 394 |
downloaded_file_path = civ_api_down(url, directory, civitai_api_key, civ_filename)
|
| 395 |
else:
|
| 396 |
-
os.system(
|
|
|
|
|
|
|
|
|
|
| 397 |
|
| 398 |
return downloaded_file_path
|
| 399 |
|
|
|
|
| 275 |
elif os.path.exists(os.path.join(dir_, filename_base)):
|
| 276 |
return os.path.join(dir_, filename_base), filename_base
|
| 277 |
|
| 278 |
+
wget_command = (
|
| 279 |
+
f'wget -c -nv '
|
| 280 |
+
f'-O "{os.path.join(dir_, filename_base)}" "{redirect_url}"'
|
| 281 |
)
|
| 282 |
+
r_code = os.system(wget_command) # noqa
|
| 283 |
|
| 284 |
# if r_code != 0:
|
| 285 |
# raise RuntimeError(f"Failed to download file: {filename_base}. Error code: {r_code}")
|
|
|
|
| 293 |
|
| 294 |
def civ_api_down(url, dir_, civitai_api_key, civ_filename):
|
| 295 |
"""
|
| 296 |
+
This method is susceptible to being blocked because it generates a lot of temp redirect links with wget.
|
| 297 |
+
If an API key limit is reached, generating a new API key and using it can fix the issue. no
|
| 298 |
"""
|
| 299 |
output_path = None
|
| 300 |
+
|
| 301 |
url_dl = url + f"?token={civitai_api_key}"
|
| 302 |
+
|
| 303 |
if not civ_filename:
|
| 304 |
+
wget_command = (
|
| 305 |
+
f'wget -c -nv '
|
| 306 |
+
f'-P "{dir_}" "{url_dl}"'
|
| 307 |
+
)
|
| 308 |
+
os.system(wget_command)
|
| 309 |
+
|
| 310 |
else:
|
| 311 |
output_path = os.path.join(dir_, civ_filename)
|
| 312 |
+
|
| 313 |
if not os.path.exists(output_path):
|
| 314 |
+
wget_command = (
|
| 315 |
+
f'wget -c -nv '
|
| 316 |
+
f'-O "{output_path}" "{url_dl}"'
|
| 317 |
)
|
| 318 |
+
os.system(wget_command)
|
| 319 |
+
|
| 320 |
return output_path
|
| 321 |
|
|
|
|
| 322 |
def drive_down(url, dir_):
|
| 323 |
import gdown
|
| 324 |
|
|
|
|
| 359 |
url = url.replace("/blob/", "/resolve/")
|
| 360 |
|
| 361 |
if hf_token:
|
| 362 |
+
os.system(
|
| 363 |
+
f'wget -c -nv '
|
| 364 |
+
f'--header="Authorization: Bearer {hf_token}" '
|
| 365 |
+
f'-O "{os.path.join(dir_, filename)}" "{url}"'
|
| 366 |
+
)
|
| 367 |
else:
|
| 368 |
+
os.system(
|
| 369 |
+
f'wget -c -nv '
|
| 370 |
+
f'-O "{os.path.join(dir_, filename)}" "{url}"'
|
| 371 |
+
)
|
| 372 |
|
| 373 |
return output_path
|
| 374 |
|
|
|
|
| 381 |
downloaded_file_path = drive_down(url, directory)
|
| 382 |
elif "huggingface.co" in url:
|
| 383 |
downloaded_file_path = hf_down(url, directory, hf_token, romanize)
|
| 384 |
+
elif "civitai." in url:
|
| 385 |
+
url = url.replace("civitai.red", "civitai.com")
|
| 386 |
if not civitai_api_key:
|
| 387 |
msg = "You need an API key to download Civitai models."
|
| 388 |
print(f"\033[91m{msg}\033[0m")
|
|
|
|
| 405 |
gr.Warning(msg)
|
| 406 |
downloaded_file_path = civ_api_down(url, directory, civitai_api_key, civ_filename)
|
| 407 |
else:
|
| 408 |
+
os.system(
|
| 409 |
+
f'wget -c -nv '
|
| 410 |
+
f'-P "{directory}" "{url}"'
|
| 411 |
+
)
|
| 412 |
|
| 413 |
return downloaded_file_path
|
| 414 |
|