models.py 9.4 KB

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