Dreamspire commited on
Commit
8e59d75
·
1 Parent(s): 716a0b4

Florence2ModelLoader loadmodel

Browse files
custom_nodes/comfyui-florence2/nodes.py CHANGED
@@ -198,6 +198,65 @@ class DownloadAndLoadFlorence2Lora:
198
 
199
  class Florence2ModelLoader:
200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  @classmethod
202
  def INPUT_TYPES(s):
203
  all_llm_paths = folder_paths.get_folder_paths("LLM")
@@ -223,50 +282,50 @@ class Florence2ModelLoader:
223
  FUNCTION = "loadmodel"
224
  CATEGORY = "Florence2"
225
 
226
- def loadmodel(self, model, precision, attention, lora=None, convert_to_safetensors=False):
227
- device = mm.get_torch_device()
228
- offload_device = mm.unet_offload_device()
229
- dtype = {"bf16": torch.bfloat16, "fp16": torch.float16, "fp32": torch.float32}[precision]
230
-
231
- model_path = Florence2ModelLoader.model_paths.get(model)
232
- print(f"Loading model from {model_path}")
233
- print(f"Florence2 using {attention} for attention")
234
- if convert_to_safetensors:
235
- model_weight_path = os.path.join(model_path, 'pytorch_model.bin')
236
- if os.path.exists(model_weight_path):
237
- safetensors_weight_path = os.path.join(model_path, 'model.safetensors')
238
- print(f"Converting {model_weight_path} to {safetensors_weight_path}")
239
- if not os.path.exists(safetensors_weight_path):
240
- sd = torch.load(model_weight_path, map_location=offload_device)
241
- sd_new = {}
242
- for k, v in sd.items():
243
- sd_new[k] = v.clone()
244
- save_file(sd_new, safetensors_weight_path)
245
- if os.path.exists(safetensors_weight_path):
246
- print(f"Conversion successful. Deleting original file: {model_weight_path}")
247
- os.remove(model_weight_path)
248
- print(f"Original {model_weight_path} file deleted.")
249
-
250
- if transformers.__version__ < '4.51.0':
251
- with patch("transformers.dynamic_module_utils.get_imports", fixed_get_imports): #workaround for unnecessary flash_attn requirement
252
- model = AutoModelForCausalLM.from_pretrained(model_path, attn_implementation=attention, torch_dtype=dtype,trust_remote_code=True).to(offload_device)
253
- else:
254
- from .modeling_florence2 import Florence2ForConditionalGeneration
255
- model = Florence2ForConditionalGeneration.from_pretrained(model_path, attn_implementation=attention, torch_dtype=dtype).to(offload_device)
256
- processor = AutoProcessor.from_pretrained(model_path, trust_remote_code=True)
257
-
258
- if lora is not None:
259
- from peft import PeftModel
260
- adapter_name = lora
261
- model = PeftModel.from_pretrained(model, adapter_name, trust_remote_code=True)
262
 
263
- florence2_model = {
264
- 'model': model,
265
- 'processor': processor,
266
- 'dtype': dtype
267
- }
268
 
269
- return (florence2_model,)
270
 
271
  class Florence2Run:
272
  @classmethod
 
198
 
199
  class Florence2ModelLoader:
200
 
201
+ # 用下面的函数完整替换掉旧的 loadmodel 函数
202
+ def loadmodel(self, model, precision, attention, lora=None, convert_to_safetensors=False):
203
+ """
204
+ 一个为 Hugging Face Spaces ZeroGPU 环境重写的、稳健的 loadmodel 函数。
205
+ 它完全移除了手动的设备管理,并使用 accelerate 库进行智能调度。
206
+ """
207
+ # 1. 彻底删除所有手动的设备管理
208
+ # device = mm.get_torch_device() <-- 已删除
209
+ # offload_device = mm.unet_offload_device() <-- 已删除
210
+
211
+ dtype = {"bf16": torch.bfloat16, "fp16": torch.float16, "fp32": torch.float32}[precision]
212
+
213
+ model_path = self.model_paths.get(model)
214
+ print(f"Loading model from {model_path} using the correct Spaces method (device_map='auto').")
215
+
216
+ # 2. 保留 safetensors 转换逻辑,但修复 map_location
217
+ if convert_to_safetensors:
218
+ model_weight_path = os.path.join(model_path, 'pytorch_model.bin')
219
+ safetensors_weight_path = os.path.join(model_path, 'model.safetensors')
220
+ if os.path.exists(model_weight_path) and not os.path.exists(safetensors_weight_path):
221
+ print(f"Converting {model_weight_path} to {safetensors_weight_path}")
222
+ # 使用 "cpu" 作为 map_location 确保在任何环境下都安全
223
+ sd = torch.load(model_weight_path, map_location="cpu")
224
+ save_file(sd, safetensors_weight_path)
225
+ if os.path.exists(safetensors_weight_path):
226
+ os.remove(model_weight_path)
227
+ print(f"Conversion successful. Original file deleted.")
228
+
229
+ # 3. 统一使用 from_pretrained 和 device_map="auto" 加载模型
230
+ # 删除所有 .to(device) 调用
231
+
232
+ # 假设 Florence2ForConditionalGeneration 是你的主要模型类
233
+ from .modeling_florence2 import Florence2ForConditionalGeneration
234
+
235
+ print("Loading model with device_map='auto'...")
236
+ model_instance = Florence2ForConditionalGeneration.from_pretrained(
237
+ model_path,
238
+ attn_implementation=attention,
239
+ torch_dtype=dtype,
240
+ device_map="auto",
241
+ low_cpu_mem_usage=True # 强烈推荐,防止CPU内存溢出
242
+ )
243
+ print("Model loaded successfully onto meta device / CPU.")
244
+
245
+ processor = AutoProcessor.from_pretrained(model_path, trust_remote_code=True)
246
+
247
+ if lora is not None:
248
+ from peft import PeftModel
249
+ # PEFT 会自动处理设备,无需改动
250
+ model_instance = PeftModel.from_pretrained(model_instance, lora, trust_remote_code=True)
251
+
252
+ florence2_model = {
253
+ 'model': model_instance,
254
+ 'processor': processor,
255
+ 'dtype': dtype
256
+ }
257
+
258
+ return (florence2_model,) # 保持返回元组的格式
259
+
260
  @classmethod
261
  def INPUT_TYPES(s):
262
  all_llm_paths = folder_paths.get_folder_paths("LLM")
 
282
  FUNCTION = "loadmodel"
283
  CATEGORY = "Florence2"
284
 
285
+ # def loadmodel(self, model, precision, attention, lora=None, convert_to_safetensors=False):
286
+ # device = mm.get_torch_device()
287
+ # offload_device = mm.unet_offload_device()
288
+ # dtype = {"bf16": torch.bfloat16, "fp16": torch.float16, "fp32": torch.float32}[precision]
289
+
290
+ # model_path = Florence2ModelLoader.model_paths.get(model)
291
+ # print(f"Loading model from {model_path}")
292
+ # print(f"Florence2 using {attention} for attention")
293
+ # if convert_to_safetensors:
294
+ # model_weight_path = os.path.join(model_path, 'pytorch_model.bin')
295
+ # if os.path.exists(model_weight_path):
296
+ # safetensors_weight_path = os.path.join(model_path, 'model.safetensors')
297
+ # print(f"Converting {model_weight_path} to {safetensors_weight_path}")
298
+ # if not os.path.exists(safetensors_weight_path):
299
+ # sd = torch.load(model_weight_path, map_location=offload_device)
300
+ # sd_new = {}
301
+ # for k, v in sd.items():
302
+ # sd_new[k] = v.clone()
303
+ # save_file(sd_new, safetensors_weight_path)
304
+ # if os.path.exists(safetensors_weight_path):
305
+ # print(f"Conversion successful. Deleting original file: {model_weight_path}")
306
+ # os.remove(model_weight_path)
307
+ # print(f"Original {model_weight_path} file deleted.")
308
+
309
+ # if transformers.__version__ < '4.51.0':
310
+ # with patch("transformers.dynamic_module_utils.get_imports", fixed_get_imports): #workaround for unnecessary flash_attn requirement
311
+ # model = AutoModelForCausalLM.from_pretrained(model_path, attn_implementation=attention, torch_dtype=dtype,trust_remote_code=True).to(offload_device)
312
+ # else:
313
+ # from .modeling_florence2 import Florence2ForConditionalGeneration
314
+ # model = Florence2ForConditionalGeneration.from_pretrained(model_path, attn_implementation=attention, torch_dtype=dtype).to(offload_device)
315
+ # processor = AutoProcessor.from_pretrained(model_path, trust_remote_code=True)
316
+
317
+ # if lora is not None:
318
+ # from peft import PeftModel
319
+ # adapter_name = lora
320
+ # model = PeftModel.from_pretrained(model, adapter_name, trust_remote_code=True)
321
 
322
+ # florence2_model = {
323
+ # 'model': model,
324
+ # 'processor': processor,
325
+ # 'dtype': dtype
326
+ # }
327
 
328
+ # return (florence2_model,)
329
 
330
  class Florence2Run:
331
  @classmethod