2025년 10월 29일 수요일

2025-10-29 현시점에서 개인 개발자를 위한 가장 현실적인 인공지능 학습을 위한 GPU workstation

 GPU - Nvidia RTX 4090(24GB) : 학습데이터 메인메모리에서 GPU로 옮기다가 에러나가 싫으면 24GB는 되어야 한다고 생각한다.

CPU - 사실 별로 중요하지 않다. 이왕이면 AMD로

RAM - 뭐가 되었든 최소 64GB 이상 데이터를 그래프화 하거나 저장하거나 할때 말도 않되는 메모리 사용량에 프로그램이 멈추는 경험을 하기 싫다면 많을 수록 좋다.

메인보드 - 당장 GPU를 하나밖에 달 수 없는 주머니 사정을 어쩔 수 없더라도 누가 알겠는가 어쩌다 돈이 떨어져서 GPU를 하나 더 달 수 있는 상황이 발생할지도 그러니까 그러니 GPU를 어러게 달 수 있는 메인보드를 선택하자 당장은 어쩔 수 없이 하나만 달아서 쓰더라도.

 파워서플라이 - 850W 이상 끝.

Keras 정확히는 Tensorflow의 메모리 부족 문제 해결책

 처음에는 학습데이터의 양이 메인 메모리의 한계를 넘어가면서 메모리를 증설했고 그 다음에는 학습데이터를 GPU에 옮기는 과정에서 GPU 메모리가 부족하여 batch_size를 줄여도 보았으나 다음과 같은 에러 메시지는 해결되지 않았다. 

" InternalError: Failed copying input tensor from /job:localhost/replica:0/task:0/device:CPU:0 to /job:localhost/replica:0/task:0/device:GPU:0 in order to run _EagerConst: Dst tensor is not initialized."

 확실하진 않지만 위와 같은 메시지 였던것 같다. CPU에서 다루던 데이터를 GPU로 옮기다가 사고가 나는 것 같다. 이치상으로 보면 batch_size를 줄이면 해결되어야 하는데 해결되지 않았고 어디서 다음과 같은 DataGenerator로 조금씩 데이터를 흘려 주면 된다고 했는데 나한테는 전혀 효과가 없었다.


class DataGenerator(Sequence):
  def __init__(self, x_set, y_set, batch_size):
    self.x, self.y = x_set, y_set
    self.batch_size = batch_size

  def __len__(self):
    return int(np.ceil(len(self.x) / float(self.batch_size)))

  def __getitem__(self, idx):
    if idx == self.__len__() - 1:
      batch_x = self.x[idx * self.batch_size : ]
      batch_y = self.y[idx * self.batch_size : ]
    else:
      batch_x = self.x[idx * self.batch_size : (idx+1) * self.batch_size]
      batch_y = self.y[idx * self.batch_size : (idx+1) * self.batch_size]
    return batch_x, batch_y

train_gen = DataGenerator( X_train_split,  y_train_split,  batch_size)
test_gen = DataGenerator(X_val_split, y_val_split, batch_size)

history = self.model.fit(
 train_gen,
 validation_data=test_gen,
 epochs=epochs,
 callbacks=callbacks,
 verbose=1

 정확히 문제가 되는 지점이 학습 완료 후 평가하는 과정에서 사단이 나서 굉장히 열받는 상황이었다. 며칠을 걸려서 학습을 완료했는데 왜 평가할때 프로그램이 사망하냐구.

 아무튼 좀 더 구글링을 해서 찾은 해결책은 학습기간 동안 최적의 모델을 파일형태로 저장하도록 하고 기존 모델을 제거해서 메모리 문제를 제거하는 방법을 시도해 보았다. 그리고 최적의 모델은 다시 파일에서 로딩하는 방식으로... 하지만 다음 명령어는 효과가 없었다.

del model

 뭔가 cuda와 cuDNN 그리고 tensorflow의 backend 사이에 꼬여 있는 부분이 있는 것 같다. 여러 차례의 시도를 하여 각 tensorflow의 backend의 각세션을 학습 완료 후 재 초기화 하고 "del model"을  수행한다. 그리고 garbage collect을 통해 안쓰는 데이터를 메모리에서 해제한다. 그 결과 평가 단계로 수훨하게 넘어 갈 수 있었다. 그 기록을 여기에 남겨 둔다.

 ... 학습 완료 후...

    # reset Keras Session
    sess = tf.compat.v1.keras.backend.get_session()
    tf.compat.v1.keras.backend.clear_session()
    sess.close()
    sess = tf.compat.v1.keras.backend.get_session()
    del self.model  # this is from global space - change this as you need
    # use the same config as you used to create the session
    config = tf.compat.v1.ConfigProto()
    config.gpu_options.per_process_gpu_memory_fraction = 1
    config.gpu_options.visible_device_list = "0"
    tf.compat.v1.keras.backend.set_session(tf.compat.v1.Session(config=config))

    import gc

    gc.collect()

... 저장된 파일에서 self.model을 다시 로드한다...