models.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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,
  15. Policy, str2bool)
  16. if shared.args.deepspeed:
  17. import deepspeed
  18. from transformers.deepspeed import (HfDeepSpeedConfig,
  19. is_deepspeed_zero3_enabled)
  20. from modules.deepspeed_parameters import generate_ds_config
  21. # Distributed setup
  22. local_rank = shared.args.local_rank if shared.args.local_rank is not None else int(os.getenv("LOCAL_RANK", "0"))
  23. world_size = int(os.getenv("WORLD_SIZE", "1"))
  24. torch.cuda.set_device(local_rank)
  25. deepspeed.init_distributed()
  26. ds_config = generate_ds_config(shared.args.bf16, 1 * world_size, shared.args.nvme_offload_dir)
  27. dschf = HfDeepSpeedConfig(ds_config) # Keep this object alive for the Transformers integration
  28. def load_model(model_name):
  29. print(f"Loading {model_name}...")
  30. t0 = time.time()
  31. shared.is_RWKV = model_name.lower().startswith('rwkv-')
  32. # Default settings
  33. if not (shared.args.cpu or shared.args.load_in_8bit 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):
  34. if any(size in shared.model_name.lower() for size in ('13b', '20b', '30b')):
  35. model = AutoModelForCausalLM.from_pretrained(Path(f"models/{shared.model_name}"), device_map='auto', load_in_8bit=True)
  36. else:
  37. 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()
  38. # FlexGen
  39. elif shared.args.flexgen:
  40. # Initialize environment
  41. env = ExecutionEnv.create(shared.args.disk_cache_dir)
  42. # Offloading policy
  43. policy = Policy(1, 1,
  44. shared.args.percent[0], shared.args.percent[1],
  45. shared.args.percent[2], shared.args.percent[3],
  46. shared.args.percent[4], shared.args.percent[5],
  47. overlap=True, sep_layer=True, pin_weight=True,
  48. cpu_cache_compute=False, attn_sparsity=1.0,
  49. compress_weight=shared.args.compress_weight,
  50. comp_weight_config=CompressionConfig(
  51. num_bits=4, group_size=64,
  52. group_dim=0, symmetric=False),
  53. compress_cache=False,
  54. comp_cache_config=CompressionConfig(
  55. num_bits=4, group_size=64,
  56. group_dim=2, symmetric=False))
  57. model = OptLM(f"facebook/{shared.model_name}", env, "models", policy)
  58. # DeepSpeed ZeRO-3
  59. elif shared.args.deepspeed:
  60. model = AutoModelForCausalLM.from_pretrained(Path(f"models/{shared.model_name}"), torch_dtype=torch.bfloat16 if shared.args.bf16 else torch.float16)
  61. model = deepspeed.initialize(model=model, config_params=ds_config, model_parameters=None, optimizer=None, lr_scheduler=None)[0]
  62. model.module.eval() # Inference
  63. print(f"DeepSpeed ZeRO-3 is enabled: {is_deepspeed_zero3_enabled()}")
  64. # RMKV model (not on HuggingFace)
  65. elif shared.is_RWKV:
  66. import types
  67. np.set_printoptions(precision=4, suppress=True, linewidth=200)
  68. os.environ['RWKV_JIT_ON'] = '1'
  69. os.environ["RWKV_CUDA_ON"] = '0' # '1' : use CUDA kernel for seq mode (much faster)
  70. from rwkv.model import RWKV
  71. from rwkv.utils import PIPELINE, PIPELINE_ARGS
  72. model = RWKV(model='models/RWKV-4-Pile-169M-20220807-8023.pth', strategy='cuda fp16')
  73. out, state = model.forward([187, 510, 1563, 310, 247], None) # use 20B_tokenizer.json
  74. print(out.detach().cpu().numpy()) # get logits
  75. out, state = model.forward([187, 510], None)
  76. out, state = model.forward([1563], state) # RNN has state (use deepcopy if you want to clone it)
  77. out, state = model.forward([310, 247], state)
  78. print(out.detach().cpu().numpy()) # same result as above
  79. pipeline = PIPELINE(model, "20B_tokenizer.json")
  80. return pipeline, None
  81. # Custom
  82. else:
  83. command = "AutoModelForCausalLM.from_pretrained"
  84. params = ["low_cpu_mem_usage=True"]
  85. if not shared.args.cpu and not torch.cuda.is_available():
  86. print("Warning: no GPU has been detected.\nFalling back to CPU mode.\n")
  87. shared.args.cpu = True
  88. if shared.args.cpu:
  89. params.append("low_cpu_mem_usage=True")
  90. params.append("torch_dtype=torch.float32")
  91. else:
  92. params.append("device_map='auto'")
  93. 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")
  94. if shared.args.gpu_memory:
  95. memory_map = shared.args.gpu_memory
  96. max_memory = f"max_memory={{0: '{memory_map[0]}GiB'"
  97. for i in range(1, len(memory_map)):
  98. max_memory += (f", {i}: '{memory_map[i]}GiB'")
  99. max_memory += (f", 'cpu': '{shared.args.cpu_memory or '99'}GiB'}}")
  100. params.append(max_memory)
  101. elif not shared.args.load_in_8bit:
  102. total_mem = (torch.cuda.get_device_properties(0).total_memory/(1024*1024))
  103. suggestion = round((total_mem-1000)/1000)*1000
  104. if total_mem-suggestion < 800:
  105. suggestion -= 1000
  106. suggestion = int(round(suggestion/1000))
  107. 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")
  108. params.append(f"max_memory={{0: '{suggestion}GiB', 'cpu': '{shared.args.cpu_memory or '99'}GiB'}}")
  109. if shared.args.disk:
  110. params.append(f"offload_folder='{shared.args.disk_cache_dir}'")
  111. command = f"{command}(Path(f'models/{shared.model_name}'), {', '.join(set(params))})"
  112. model = eval(command)
  113. # Loading the tokenizer
  114. if shared.model_name.lower().startswith(('gpt4chan', 'gpt-4chan', '4chan')) and Path("models/gpt-j-6B/").exists():
  115. tokenizer = AutoTokenizer.from_pretrained(Path("models/gpt-j-6B/"))
  116. else:
  117. tokenizer = AutoTokenizer.from_pretrained(Path(f"models/{shared.model_name}/"))
  118. tokenizer.truncation_side = 'left'
  119. print(f"Loaded the model in {(time.time()-t0):.2f} seconds.")
  120. return model, tokenizer
  121. def load_soft_prompt(name):
  122. if name == 'None':
  123. shared.soft_prompt = False
  124. shared.soft_prompt_tensor = None
  125. else:
  126. with zipfile.ZipFile(Path(f'softprompts/{name}.zip')) as zf:
  127. zf.extract('tensor.npy')
  128. zf.extract('meta.json')
  129. j = json.loads(open('meta.json', 'r').read())
  130. print(f"\nLoading the softprompt \"{name}\".")
  131. for field in j:
  132. if field != 'name':
  133. if type(j[field]) is list:
  134. print(f"{field}: {', '.join(j[field])}")
  135. else:
  136. print(f"{field}: {j[field]}")
  137. print()
  138. tensor = np.load('tensor.npy')
  139. Path('tensor.npy').unlink()
  140. Path('meta.json').unlink()
  141. tensor = torch.Tensor(tensor).to(device=shared.model.device, dtype=shared.model.dtype)
  142. tensor = torch.reshape(tensor, (1, tensor.shape[0], tensor.shape[1]))
  143. shared.soft_prompt = True
  144. shared.soft_prompt_tensor = tensor
  145. return name