tori29umai commited on
Commit
5ca42f5
·
verified ·
1 Parent(s): c29ee6b

Update diffusers_helper/memory.py

Browse files
Files changed (1) hide show
  1. diffusers_helper/memory.py +40 -33
diffusers_helper/memory.py CHANGED
@@ -1,36 +1,37 @@
1
  # By lllyasviel
2
-
3
 
4
  import torch
5
  import os
6
 
7
- # 检查是否在Hugging Face Space环境中
8
  IN_HF_SPACE = os.environ.get('SPACE_ID') is not None
9
 
10
- # 设置CPU设备
11
  cpu = torch.device('cpu')
12
 
13
- # 在Stateless GPU环境中,不要在主进程初始化CUDA
14
  def get_gpu_device():
15
  if IN_HF_SPACE:
16
- # Spaces中将延迟初始化GPU设备
17
- return 'cuda' # 返回字符串,而不是实际初始化设备
18
 
19
- # 非Spaces环境正常初始化
20
  try:
21
  if torch.cuda.is_available():
22
  return torch.device(f'cuda:{torch.cuda.current_device()}')
23
  else:
24
- print("CUDA不可用,使用CPU作为默认设备")
25
  return torch.device('cpu')
26
  except Exception as e:
27
- print(f"初始化CUDA设备时出错: {e}")
28
- print("回退到CPU设备")
29
  return torch.device('cpu')
30
 
31
- # 保存一个字符串表示,而不是实际的设备对象
32
  gpu = get_gpu_device()
33
 
 
34
  gpu_complete_modules = []
35
 
36
 
@@ -83,7 +84,7 @@ class DynamicSwapInstaller:
83
 
84
 
85
  def fake_diffusers_current_device(model: torch.nn.Module, target_device):
86
- # 转换字符串设备为torch.device
87
  if isinstance(target_device, str):
88
  target_device = torch.device(target_device)
89
 
@@ -101,14 +102,14 @@ def get_cuda_free_memory_gb(device=None):
101
  if device is None:
102
  device = gpu
103
 
104
- # 如果是字符串,转换为设备
105
  if isinstance(device, str):
106
  device = torch.device(device)
107
 
108
- # 如果不是CUDA设备,返回默认值
109
  if device.type != 'cuda':
110
- print("无法获取非CUDA设备的内存信息,返回默认值")
111
- return 6.0 # 返回一个默认值
112
 
113
  try:
114
  memory_stats = torch.cuda.memory_stats(device)
@@ -119,26 +120,27 @@ def get_cuda_free_memory_gb(device=None):
119
  bytes_total_available = bytes_free_cuda + bytes_inactive_reserved
120
  return bytes_total_available / (1024 ** 3)
121
  except Exception as e:
122
- print(f"获取CUDA内存信息时出错: {e}")
123
- return 6.0 # 返回一个默认值
124
 
125
 
126
  def move_model_to_device_with_memory_preservation(model, target_device, preserved_memory_gb=0):
127
- print(f'Moving {model.__class__.__name__} to {target_device} with preserved memory: {preserved_memory_gb} GB')
128
 
129
- # 如果是字符串,转换为设备
130
  if isinstance(target_device, str):
131
  target_device = torch.device(target_device)
132
 
133
- # 如果gpu是字符串,转换为设备
134
  gpu_device = gpu
135
  if isinstance(gpu_device, str):
136
  gpu_device = torch.device(gpu_device)
137
 
138
- # 如果目标设备是CPU或当前在CPU上,直接移动
139
  if target_device.type == 'cpu' or gpu_device.type == 'cpu':
140
  model.to(device=target_device)
141
- torch.cuda.empty_cache() if torch.cuda.is_available() else None
 
142
  return
143
 
144
  for m in model.modules():
@@ -155,21 +157,22 @@ def move_model_to_device_with_memory_preservation(model, target_device, preserve
155
 
156
 
157
  def offload_model_from_device_for_memory_preservation(model, target_device, preserved_memory_gb=0):
158
- print(f'Offloading {model.__class__.__name__} from {target_device} to preserve memory: {preserved_memory_gb} GB')
159
 
160
- # 如果是字符串,转换为设备
161
  if isinstance(target_device, str):
162
  target_device = torch.device(target_device)
163
 
164
- # 如果gpu是字符串,转换为设备
165
  gpu_device = gpu
166
  if isinstance(gpu_device, str):
167
  gpu_device = torch.device(gpu_device)
168
 
169
- # 如果目标设备是CPU或当前在CPU上,直接处理
170
  if target_device.type == 'cpu' or gpu_device.type == 'cpu':
171
  model.to(device=cpu)
172
- torch.cuda.empty_cache() if torch.cuda.is_available() else None
 
173
  return
174
 
175
  for m in model.modules():
@@ -187,16 +190,19 @@ def offload_model_from_device_for_memory_preservation(model, target_device, pres
187
 
188
  def unload_complete_models(*args):
189
  for m in gpu_complete_modules + list(args):
 
 
190
  m.to(device=cpu)
191
- print(f'Unloaded {m.__class__.__name__} as complete.')
192
 
193
  gpu_complete_modules.clear()
194
- torch.cuda.empty_cache() if torch.cuda.is_available() else None
 
195
  return
196
 
197
 
198
  def load_model_as_complete(model, target_device, unload=True):
199
- # 如果是字符串,转换为设备
200
  if isinstance(target_device, str):
201
  target_device = torch.device(target_device)
202
 
@@ -204,6 +210,7 @@ def load_model_as_complete(model, target_device, unload=True):
204
  unload_complete_models()
205
 
206
  model.to(device=target_device)
207
- print(f'Loaded {model.__class__.__name__} to {target_device} as complete.')
208
 
209
- gpu_complete_modules.append(model)
 
 
1
  # By lllyasviel
2
+ # WindowsとHugging Face Space環境の両方に対応した統合バージョン
3
 
4
  import torch
5
  import os
6
 
7
+ # Hugging Face Space環境で実行されているかどうかを確認
8
  IN_HF_SPACE = os.environ.get('SPACE_ID') is not None
9
 
10
+ # CPU デバイスを設定
11
  cpu = torch.device('cpu')
12
 
13
+ # ステートレスGPU環境では、メインプロセスでCUDAを初期化しない
14
  def get_gpu_device():
15
  if IN_HF_SPACE:
16
+ # Spacesではデバイスの初期化を遅延させる
17
+ return 'cuda' # 実際のデバイスを初期化せず、文字列を返す
18
 
19
+ # 非Space環境では通常通り初期化
20
  try:
21
  if torch.cuda.is_available():
22
  return torch.device(f'cuda:{torch.cuda.current_device()}')
23
  else:
24
+ print("CUDAが利用できません。デフォルトデバイスとしてCPUを使用します")
25
  return torch.device('cpu')
26
  except Exception as e:
27
+ print(f"CUDAデバイスの初期化中にエラーが発生しました: {e}")
28
+ print("CPUデバイスにフォールバックします")
29
  return torch.device('cpu')
30
 
31
+ # GPUデバイスを取得(文字列または実際のデバイスオブジェクト)
32
  gpu = get_gpu_device()
33
 
34
+ # 完全にGPUにロードされたモジュールのリスト
35
  gpu_complete_modules = []
36
 
37
 
 
84
 
85
 
86
  def fake_diffusers_current_device(model: torch.nn.Module, target_device):
87
+ # 文字列デバイスをtorch.deviceに変換
88
  if isinstance(target_device, str):
89
  target_device = torch.device(target_device)
90
 
 
102
  if device is None:
103
  device = gpu
104
 
105
+ # デバイスが文字列の場合、デバイスオブジェクトに変換
106
  if isinstance(device, str):
107
  device = torch.device(device)
108
 
109
+ # CUDAデバイスでない場合、デフォルト値を返す
110
  if device.type != 'cuda':
111
+ print("CUDAデバイスのメモリ情報を取得できません。デフォルト値を返します")
112
+ return 6.0 # デフォルト値
113
 
114
  try:
115
  memory_stats = torch.cuda.memory_stats(device)
 
120
  bytes_total_available = bytes_free_cuda + bytes_inactive_reserved
121
  return bytes_total_available / (1024 ** 3)
122
  except Exception as e:
123
+ print(f"CUDAメモリ情報の取得中にエラーが発生しました: {e}")
124
+ return 6.0 # デフォルト値
125
 
126
 
127
  def move_model_to_device_with_memory_preservation(model, target_device, preserved_memory_gb=0):
128
+ print(f'{model.__class__.__name__} {target_device} に移動します。保持メモリ: {preserved_memory_gb} GB')
129
 
130
+ # デバイスが文字列の場合、デバイスオブジェクトに変換
131
  if isinstance(target_device, str):
132
  target_device = torch.device(target_device)
133
 
134
+ # gpuが文字列の場合、デバイスオブジェクトに変換
135
  gpu_device = gpu
136
  if isinstance(gpu_device, str):
137
  gpu_device = torch.device(gpu_device)
138
 
139
+ # 対象デバイスがCPUまたは現在CPUにある場合、直接移動
140
  if target_device.type == 'cpu' or gpu_device.type == 'cpu':
141
  model.to(device=target_device)
142
+ if torch.cuda.is_available():
143
+ torch.cuda.empty_cache()
144
  return
145
 
146
  for m in model.modules():
 
157
 
158
 
159
  def offload_model_from_device_for_memory_preservation(model, target_device, preserved_memory_gb=0):
160
+ print(f'メモリ保持のため {model.__class__.__name__} {target_device} からオフロードします: {preserved_memory_gb} GB')
161
 
162
+ # デバイスが文字列の場合、デバイスオブジェクトに変換
163
  if isinstance(target_device, str):
164
  target_device = torch.device(target_device)
165
 
166
+ # gpuが文字列の場合、デバイスオブジェクトに変換
167
  gpu_device = gpu
168
  if isinstance(gpu_device, str):
169
  gpu_device = torch.device(gpu_device)
170
 
171
+ # 対象デバイスがCPUまたは現在CPUにある場合、直接処理
172
  if target_device.type == 'cpu' or gpu_device.type == 'cpu':
173
  model.to(device=cpu)
174
+ if torch.cuda.is_available():
175
+ torch.cuda.empty_cache()
176
  return
177
 
178
  for m in model.modules():
 
190
 
191
  def unload_complete_models(*args):
192
  for m in gpu_complete_modules + list(args):
193
+ if m is None: # Noneの場合はスキップ
194
+ continue
195
  m.to(device=cpu)
196
+ print(f'{m.__class__.__name__} を完全にアンロードしました')
197
 
198
  gpu_complete_modules.clear()
199
+ if torch.cuda.is_available():
200
+ torch.cuda.empty_cache()
201
  return
202
 
203
 
204
  def load_model_as_complete(model, target_device, unload=True):
205
+ # デバイスが文字列の場合、デバイスオブジェクトに変換
206
  if isinstance(target_device, str):
207
  target_device = torch.device(target_device)
208
 
 
210
  unload_complete_models()
211
 
212
  model.to(device=target_device)
213
+ print(f'{model.__class__.__name__} {target_device} に完全にロードしました')
214
 
215
+ gpu_complete_modules.append(model)
216
+ return