models.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import json
  2. import os
  3. import time
  4. import zipfile
  5. from pathlib import Path
  6. import numpy as np
  7. import torch
  8. import transformers
  9. from transformers import AutoModelForCausalLM, AutoTokenizer
  10. import modules.shared as shared
  11. transformers.logging.set_verbosity_error()
  12. local_rank = None
  13. if shared.args.flexgen:
  14. from flexgen.flex_opt import CompressionConfig, ExecutionEnv, OptLM, Policy
  15. if shared.args.deepspeed:
  16. import deepspeed
  17. from transformers.deepspeed import (HfDeepSpeedConfig,
  18. is_deepspeed_zero3_enabled)
  19. from modules.deepspeed_parameters import generate_ds_config
  20. # Distributed setup
  21. local_rank = shared.args.local_rank if shared.args.local_rank is not None else int(os.getenv("LOCAL_RANK", "0"))
  22. world_size = int(os.getenv("WORLD_SIZE", "1"))
  23. torch.cuda.set_device(local_rank)
  24. deepspeed.init_distributed()
  25. ds_config = generate_ds_config(shared.args.bf16, 1 * world_size, shared.args.nvme_offload_dir)
  26. dschf = HfDeepSpeedConfig(ds_config) # Keep this object alive for the Transformers integration
  27. def load_model(model_name):
  28. print(f"Loading {model_name}...")
  29. t0 = time.time()
  30. shared.is_RWKV = model_name.lower().startswith('rwkv-')
  31. # Default settings
  32. if not any([shared.args.cpu, shared.args.load_in_8bit, shared.args.gptq_bits, shared.args.auto_devices, shared.args.disk, shared.args.gpu_memory is not None, shared.args.cpu_memory is not None, shared.args.deepspeed, shared.args.flexgen, shared.is_RWKV]):
  33. if any(size in shared.model_name.lower() for size in ('13b', '20b', '30b')):
  34. model = AutoModelForCausalLM.from_pretrained(Path(f"models/{shared.model_name}"), device_map='auto', load_in_8bit=True)
  35. else:
  36. model = AutoModelForCausalLM.from_pretrained(Path(f"models/{shared.model_name}"), low_cpu_mem_usage=True, torch_dtype=torch.bfloat16 if shared.args.bf16 else torch.float16).cuda()
  37. # FlexGen
  38. elif shared.args.flexgen:
  39. # Initialize environment
  40. env = ExecutionEnv.create(shared.args.disk_cache_dir)
  41. # Offloading policy
  42. policy = Policy(1, 1,
  43. shared.args.percent[0], shared.args.percent[1],
  44. shared.args.percent[2], shared.args.percent[3],
  45. shared.args.percent[4], shared.args.percent[5],
  46. overlap=True, sep_layer=True, pin_weight=shared.args.pin_weight,
  47. cpu_cache_compute=False, attn_sparsity=1.0,
  48. compress_weight=shared.args.compress_weight,
  49. comp_weight_config=CompressionConfig(
  50. num_bits=4, group_size=64,
  51. group_dim=0, symmetric=False),
  52. compress_cache=False,
  53. comp_cache_config=CompressionConfig(
  54. num_bits=4, group_size=64,
  55. group_dim=2, symmetric=False))
  56. model = OptLM(f"facebook/{shared.model_name}", env, "models", policy)
  57. # DeepSpeed ZeRO-3
  58. elif shared.args.deepspeed:
  59. model = AutoModelForCausalLM.from_pretrained(Path(f"models/{shared.model_name}"), torch_dtype=torch.bfloat16 if shared.args.bf16 else torch.float16)
  60. model = deepspeed.initialize(model=model, config_params=ds_config, model_parameters=None, optimizer=None, lr_scheduler=None)[0]
  61. model.module.eval() # Inference
  62. print(f"DeepSpeed ZeRO-3 is enabled: {is_deepspeed_zero3_enabled()}")
  63. # RMKV model (not on HuggingFace)
  64. elif shared.is_RWKV:
  65. from modules.RWKV import RWKVModel, RWKVTokenizer
  66. model = RWKVModel.from_pretrained(Path(f'models/{model_name}'), dtype="fp32" if shared.args.cpu else "bf16" if shared.args.bf16 else "fp16", device="cpu" if shared.args.cpu else "cuda")
  67. tokenizer = RWKVTokenizer.from_pretrained(Path('models'))
  68. return model, tokenizer
  69. # Quantized model
  70. elif shared.args.gptq_bits > 0:
  71. from modules.GPTQ_loader import load_quantized
  72. model = load_quantized(model_name)
  73. # Custom
  74. else:
  75. command = "AutoModelForCausalLM.from_pretrained"
  76. params = ["low_cpu_mem_usage=True"]
  77. if not shared.args.cpu and not torch.cuda.is_available():
  78. print("Warning: torch.cuda.is_available() returned False.\nThis means that no GPU has been detected.\nFalling back to CPU mode.\n")
  79. shared.args.cpu = True
  80. if shared.args.cpu:
  81. params.append("low_cpu_mem_usage=True")
  82. params.append("torch_dtype=torch.float32")
  83. else:
  84. params.append("device_map='auto'")
  85. params.append("load_in_8bit=True" if shared.args.load_in_8bit else "torch_dtype=torch.bfloat16" if shared.args.bf16 else "torch_dtype=torch.float16")
  86. if shared.args.gpu_memory:
  87. memory_map = shared.args.gpu_memory
  88. max_memory = f"max_memory={{0: '{memory_map[0]}GiB'"
  89. for i in range(1, len(memory_map)):
  90. max_memory += (f", {i}: '{memory_map[i]}GiB'")
  91. max_memory += (f", 'cpu': '{shared.args.cpu_memory or '99'}GiB'}}")
  92. params.append(max_memory)
  93. elif not shared.args.load_in_8bit:
  94. total_mem = (torch.cuda.get_device_properties(0).total_memory/(1024*1024))
  95. suggestion = round((total_mem-1000)/1000)*1000
  96. if total_mem-suggestion < 800:
  97. suggestion -= 1000
  98. suggestion = int(round(suggestion/1000))
  99. print(f"\033[1;32;1mAuto-assiging --gpu-memory {suggestion} for your GPU to try to prevent out-of-memory errors.\nYou can manually set other values.\033[0;37;0m")
  100. params.append(f"max_memory={{0: '{suggestion}GiB', 'cpu': '{shared.args.cpu_memory or '99'}GiB'}}")
  101. if shared.args.disk:
  102. params.append(f"offload_folder='{shared.args.disk_cache_dir}'")
  103. command = f"{command}(Path(f'models/{shared.model_name}'), {', '.join(set(params))})"
  104. model = eval(command)
  105. # Loading the tokenizer
  106. if shared.model_name.lower().startswith(('gpt4chan', 'gpt-4chan', '4chan')) and Path("models/gpt-j-6B/").exists():
  107. tokenizer = AutoTokenizer.from_pretrained(Path("models/gpt-j-6B/"))
  108. else:
  109. tokenizer = AutoTokenizer.from_pretrained(Path(f"models/{shared.model_name}/"))
  110. tokenizer.truncation_side = 'left'
  111. print(f"Loaded the model in {(time.time()-t0):.2f} seconds.")
  112. return model, tokenizer
  113. def load_soft_prompt(name):
  114. if name == 'None':
  115. shared.soft_prompt = False
  116. shared.soft_prompt_tensor = None
  117. else:
  118. with zipfile.ZipFile(Path(f'softprompts/{name}.zip')) as zf:
  119. zf.extract('tensor.npy')
  120. zf.extract('meta.json')
  121. j = json.loads(open('meta.json', 'r').read())
  122. print(f"\nLoading the softprompt \"{name}\".")
  123. for field in j:
  124. if field != 'name':
  125. if type(j[field]) is list:
  126. print(f"{field}: {', '.join(j[field])}")
  127. else:
  128. print(f"{field}: {j[field]}")
  129. print()
  130. tensor = np.load('tensor.npy')
  131. Path('tensor.npy').unlink()
  132. Path('meta.json').unlink()
  133. tensor = torch.Tensor(tensor).to(device=shared.model.device, dtype=shared.model.dtype)
  134. tensor = torch.reshape(tensor, (1, tensor.shape[0], tensor.shape[1]))
  135. shared.soft_prompt = True
  136. shared.soft_prompt_tensor = tensor
  137. return name