models.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import json
  2. import os
  3. import sys
  4. import time
  5. import zipfile
  6. from pathlib import Path
  7. import numpy as np
  8. import torch
  9. import transformers
  10. from transformers import AutoModelForCausalLM, AutoTokenizer
  11. import modules.shared as shared
  12. transformers.logging.set_verbosity_error()
  13. local_rank = None
  14. if shared.args.flexgen:
  15. from flexgen.flex_opt import (CompressionConfig, ExecutionEnv, OptLM,
  16. Policy, str2bool)
  17. if shared.args.deepspeed:
  18. import deepspeed
  19. from transformers.deepspeed import (HfDeepSpeedConfig,
  20. is_deepspeed_zero3_enabled)
  21. from modules.deepspeed_parameters import generate_ds_config
  22. # Distributed setup
  23. local_rank = shared.args.local_rank if shared.args.local_rank is not None else int(os.getenv("LOCAL_RANK", "0"))
  24. world_size = int(os.getenv("WORLD_SIZE", "1"))
  25. torch.cuda.set_device(local_rank)
  26. deepspeed.init_distributed()
  27. ds_config = generate_ds_config(shared.args.bf16, 1 * world_size, shared.args.nvme_offload_dir)
  28. dschf = HfDeepSpeedConfig(ds_config) # Keep this object alive for the Transformers integration
  29. def load_model(model_name):
  30. print(f"Loading {model_name}...")
  31. t0 = time.time()
  32. shared.is_RWKV = model_name.lower().startswith('rwkv-')
  33. # Default settings
  34. if not (shared.args.cpu or shared.args.load_in_8bit or shared.args.llama_bits>0 or shared.args.auto_devices or shared.args.disk or shared.args.gpu_memory is not None or shared.args.cpu_memory is not None or shared.args.deepspeed or shared.args.flexgen or shared.is_RWKV):
  35. if any(size in shared.model_name.lower() for size in ('13b', '20b', '30b')):
  36. model = AutoModelForCausalLM.from_pretrained(Path(f"models/{shared.model_name}"), device_map='auto', load_in_8bit=True)
  37. else:
  38. 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()
  39. # FlexGen
  40. elif shared.args.flexgen:
  41. # Initialize environment
  42. env = ExecutionEnv.create(shared.args.disk_cache_dir)
  43. # Offloading policy
  44. policy = Policy(1, 1,
  45. shared.args.percent[0], shared.args.percent[1],
  46. shared.args.percent[2], shared.args.percent[3],
  47. shared.args.percent[4], shared.args.percent[5],
  48. overlap=True, sep_layer=True, pin_weight=shared.args.pin_weight,
  49. cpu_cache_compute=False, attn_sparsity=1.0,
  50. compress_weight=shared.args.compress_weight,
  51. comp_weight_config=CompressionConfig(
  52. num_bits=4, group_size=64,
  53. group_dim=0, symmetric=False),
  54. compress_cache=False,
  55. comp_cache_config=CompressionConfig(
  56. num_bits=4, group_size=64,
  57. group_dim=2, symmetric=False))
  58. model = OptLM(f"facebook/{shared.model_name}", env, "models", policy)
  59. # DeepSpeed ZeRO-3
  60. elif shared.args.deepspeed:
  61. model = AutoModelForCausalLM.from_pretrained(Path(f"models/{shared.model_name}"), torch_dtype=torch.bfloat16 if shared.args.bf16 else torch.float16)
  62. model = deepspeed.initialize(model=model, config_params=ds_config, model_parameters=None, optimizer=None, lr_scheduler=None)[0]
  63. model.module.eval() # Inference
  64. print(f"DeepSpeed ZeRO-3 is enabled: {is_deepspeed_zero3_enabled()}")
  65. # RMKV model (not on HuggingFace)
  66. elif shared.is_RWKV:
  67. from modules.RWKV import RWKVModel, RWKVTokenizer
  68. 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")
  69. tokenizer = RWKVTokenizer.from_pretrained(Path('models'))
  70. return model, tokenizer
  71. # 4-bit LLaMA
  72. elif shared.args.llama_bits>0:
  73. sys.path.insert(0, os.path.abspath(Path("repositories/GPTQ-for-LLaMa")))
  74. bits = shared.args.llama_bits
  75. from llama import load_quant
  76. path_to_model = Path(f'models/{model_name}')
  77. pt_model = ''
  78. if path_to_model.name.lower().startswith('llama-7b'):
  79. pt_model = f'llama-7b-{bits}bit.pt'
  80. elif path_to_model.name.lower().startswith('llama-13b'):
  81. pt_model = f'llama-13b-{bits}bit.pt'
  82. elif path_to_model.name.lower().startswith('llama-30b'):
  83. pt_model = f'llama-30b-{bits}bit.pt'
  84. elif path_to_model.name.lower().startswith('llama-65b'):
  85. pt_model = f'llama-65b-{bits}bit.pt'
  86. else:
  87. pt_model = f'{model_name}-{bits}bit.pt'
  88. # Try to find the .pt both in models/ and in the subfolder
  89. pt_path = None
  90. for path in [Path(p) for p in [f"models/{pt_model}", f"{path_to_model}/{pt_model}"]]:
  91. if path.exists():
  92. pt_path = path
  93. if not pt_path:
  94. print(f"Could not find {pt_model}, exiting...")
  95. exit()
  96. model = load_quant(path_to_model, Path(f"{pt_path}"), bits)
  97. # Multi-GPU setup
  98. if shared.args.gpu_memory:
  99. import accelerate
  100. max_memory = {}
  101. for i in range(len(shared.args.gpu_memory)):
  102. max_memory[i] = f"{shared.args.gpu_memory[i]}GiB"
  103. max_memory['cpu'] = f"{shared.args.cpu_memory or '99'}GiB"
  104. device_map = accelerate.infer_auto_device_map(model, max_memory=max_memory, no_split_module_classes=["LLaMADecoderLayer"])
  105. model = accelerate.dispatch_model(model, device_map=device_map)
  106. # Single GPU
  107. else:
  108. model = model.to(torch.device('cuda:0'))
  109. # Custom
  110. else:
  111. command = "AutoModelForCausalLM.from_pretrained"
  112. params = ["low_cpu_mem_usage=True"]
  113. if not shared.args.cpu and not torch.cuda.is_available():
  114. print("Warning: no GPU has been detected.\nFalling back to CPU mode.\n")
  115. shared.args.cpu = True
  116. if shared.args.cpu:
  117. params.append("low_cpu_mem_usage=True")
  118. params.append("torch_dtype=torch.float32")
  119. else:
  120. params.append("device_map='auto'")
  121. 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")
  122. if shared.args.gpu_memory:
  123. memory_map = shared.args.gpu_memory
  124. max_memory = f"max_memory={{0: '{memory_map[0]}GiB'"
  125. for i in range(1, len(memory_map)):
  126. max_memory += (f", {i}: '{memory_map[i]}GiB'")
  127. max_memory += (f", 'cpu': '{shared.args.cpu_memory or '99'}GiB'}}")
  128. params.append(max_memory)
  129. elif not shared.args.load_in_8bit:
  130. total_mem = (torch.cuda.get_device_properties(0).total_memory/(1024*1024))
  131. suggestion = round((total_mem-1000)/1000)*1000
  132. if total_mem-suggestion < 800:
  133. suggestion -= 1000
  134. suggestion = int(round(suggestion/1000))
  135. 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")
  136. params.append(f"max_memory={{0: '{suggestion}GiB', 'cpu': '{shared.args.cpu_memory or '99'}GiB'}}")
  137. if shared.args.disk:
  138. params.append(f"offload_folder='{shared.args.disk_cache_dir}'")
  139. command = f"{command}(Path(f'models/{shared.model_name}'), {', '.join(set(params))})"
  140. model = eval(command)
  141. # Loading the tokenizer
  142. if shared.model_name.lower().startswith(('gpt4chan', 'gpt-4chan', '4chan')) and Path("models/gpt-j-6B/").exists():
  143. tokenizer = AutoTokenizer.from_pretrained(Path("models/gpt-j-6B/"))
  144. else:
  145. tokenizer = AutoTokenizer.from_pretrained(Path(f"models/{shared.model_name}/"))
  146. tokenizer.truncation_side = 'left'
  147. print(f"Loaded the model in {(time.time()-t0):.2f} seconds.")
  148. return model, tokenizer
  149. def load_soft_prompt(name):
  150. if name == 'None':
  151. shared.soft_prompt = False
  152. shared.soft_prompt_tensor = None
  153. else:
  154. with zipfile.ZipFile(Path(f'softprompts/{name}.zip')) as zf:
  155. zf.extract('tensor.npy')
  156. zf.extract('meta.json')
  157. j = json.loads(open('meta.json', 'r').read())
  158. print(f"\nLoading the softprompt \"{name}\".")
  159. for field in j:
  160. if field != 'name':
  161. if type(j[field]) is list:
  162. print(f"{field}: {', '.join(j[field])}")
  163. else:
  164. print(f"{field}: {j[field]}")
  165. print()
  166. tensor = np.load('tensor.npy')
  167. Path('tensor.npy').unlink()
  168. Path('meta.json').unlink()
  169. tensor = torch.Tensor(tensor).to(device=shared.model.device, dtype=shared.model.dtype)
  170. tensor = torch.reshape(tensor, (1, tensor.shape[0], tensor.shape[1]))
  171. shared.soft_prompt = True
  172. shared.soft_prompt_tensor = tensor
  173. return name