GPU로 모델 학습과 추론 실행
GPU를 사용하는 모델 학습에는 GPU를 할당한 Jupyter Code Workspace가 권장됩니다. Code Repositories의 Python 변환에서도 GPU를 요청할 수 있습니다. 모델과 라이브러리가 GPU 연산을 지원하고 해당 장치를 실제로 사용하도록 구성해야 합니다.
프로젝트의 GPU 사용 권한
GPU 리소스 큐가 할당된 프로젝트에서 시작한 작업만 GPU를 사용할 수 있습니다. 프로젝트 파일 트리 오른쪽의 깃발 아이콘으로 큐 할당을 확인합니다.
Control Panel에서 지정한 리소스 관리 관리자 그룹은 Resource Management 앱에서 프로젝트에 큐를 할당할 수 있습니다. 이 권한이 없으면 Foundry Issue로 관리자 또는 Palantir 담당자에게 요청합니다. 호스팅 구성에 따라 지원 GPU 종류가 다르며 플랫폼 인스턴스에 GPU가 하나도 없을 수도 있습니다. 필요한 GPU가 없으면 Support에 확인합니다.
Jupyter와 VS Code Workspaces
Code Workspaces의 Settings에서 GPU를 먼저 요청합니다. 그다음 Libraries 사이드바 또는 Maestro로 TensorFlow, PyTorch 등 학습 라이브러리를 설치합니다.
GPU를 추가하기 전에 설치한 라이브러리는 CPU 전용 빌드일 수 있습니다. 설치 로그나 잠금 파일의 빌드 문자열을 확인합니다. 예를 들어 cpu_py310heba74a3_3는 CPU 빌드이고 tensorflow-2.17.0-cuda120py310heb3ae67_203는 CUDA 빌드입니다.
Jupyter는 Libraries의 Lockfile에서, VS Code는 .maestro/hawk.lock에서 설치 버전을 확인합니다. Workspaces에서 meta.yaml이나 hawk.lock을 직접 편집하는 방식은 지원하지 않으므로 Libraries 또는 Maestro를 사용합니다.
__cuda 의존성을 해결하지 못할 때
GPU가 없는 작업 공간에서 CUDA 빌드를 강제로 설치하면 __cuda 가상 패키지를 찾지 못하여 환경 해결에 실패합니다. 다음과 같이 빌드를 제한하더라도 GPU 자체가 있어야 합니다.
maestro env conda install 'tensorflow=2.17.0=*cuda*'
오류에는 Unsolvable environment error, cannot be installed because there are no viable options, __cuda *, for which no candidates were found가 표시될 수 있습니다. GPU를 추가한 뒤 라이브러리를 설치합니다.
GPU를 추가해도 CPU 빌드가 남을 때
GPU 추가만으로 기존 잠금 파일을 다시 해결하지 않습니다. GPU를 추가한 후 패키지를 재설치하거나 환경을 재설정합니다.
maestro env reset --hard
의존성을 추가하거나 제거하여 환경을 다시 해결할 수도 있습니다. 잠금 파일을 수동으로 삭제하지 말고 지원하는 관리 명령을 사용합니다.
Code Repositories의 경량 변환
Python 변환에는 경량 실행을 권장합니다. 예시의 NVIDIA_T4와 출력 경로를 환경에 맞게 선택합니다. 아래 변환은 실제 GPU 장치 이름을 출력 데이터셋에 기록합니다. 저장소에 pytorch, pytorch-gpu 및 pandas 의존성을 추가해야 합니다.
import pandas as pd
import torch
from transforms.api import transform, Output, lightweight, LightweightOutput
@lightweight(gpu_type="NVIDIA_T4")
@transform(out=Output("/Project/folder/output"))
def compute(out: LightweightOutput):
out.write_pandas(pd.DataFrame({"gpu_name": [torch.cuda.get_device_name(0)]}))
Spark 변환에서는 DRIVER_GPU_ENABLED 또는 EXECUTOR_GPU_ENABLED 프로필을 프로젝트에 가져와 적용합니다. GPU 종류를 코드에 지정하지 않으며 프로젝트 큐의 장치를 사용합니다. 실행기에 학습이나 추론을 분산하는 작업은 코드 또는 라이브러리가 처리해야 합니다. Spark 분산 연산이나 Spark DataFrame이 필요한 모델이 아니라면 경량 변환으로 Spark 시작 및 데이터 변환 비용을 줄일 수 있습니다.
할당한 GPU의 종류와 실행 시간에 따른 사용량은 Code Repositories 연산 사용량에서 계산합니다.
저장소에서 CUDA 패키지 해결
이 설정은 Palantir Code Repositories UI가 관리하는 저장소에 적용합니다. 브라우저 기반 VS Code는 앞의 Workspaces 절차를 따릅니다.
저장소의 Conda 환경을 해결하는 서버와 실제 빌드 서버는 서로 다릅니다. 환경 해결 서버에는 GPU를 할당할 수 없으므로 CONDA_OVERRIDE_CUDA로 사용할 CUDA 버전을 지정합니다. GPU 작업 공간에서 nvidia-smi를 실행하면 오른쪽 위에 드라이버가 지원하는 최대 CUDA 버전이 나옵니다. 이 범위 안에서 GPU와 학습 프레임워크 모두에 맞는 버전을 선택합니다.
저장소 설정의 Show hidden files and folders를 켜고 가장 깊이 있는 build.gradle에 다음 설정을 추가합니다. 11.8은 예시 값입니다. GPU용 패키지 또는 CUDA 빌드 조건도 함께 지정합니다.
// CUDA setup
tasks.runVersions {
// 11.8 is just an example, use the latest supported
// CUDA version for your model training framework version
// and GPU/driver.
// See https://www.tensorflow.org/install/source#gpu for tensorflow
// and https://pytorch.org/get-started/locally/ under linux for pytorch.
environment("CONDA_OVERRIDE_CUDA", "11.8")
}
tasks.condaPackRun {
environment("CONDA_OVERRIDE_CUDA", "11.8")
}
최상위 build.gradle에는 추가하지 않습니다. 변환 템플릿은 transforms-python 폴더, 모델 템플릿은 transformers-model-training 폴더의 파일을 사용합니다. 설치 결과는 숨김 파일 conda-versions.run.linux-64.lock 또는 검사 로그에서 확인합니다.
변환 Preview에는 GPU를 사용할 수 없습니다. 미리보기와 실제 빌드의 동작이 달라질 수 있습니다.
Conda와 pip의 의존성
Conda는 서로 충돌하는 의존성이 있으면 설치를 거부하므로 Foundry의 transforms-python 및 palantir_models 의존성을 함께 관리할 때 권장됩니다. GPU가 없는 환경에서는 CPU 빌드를 선택할 수 있으므로 CUDA 변형이 실제로 설치되었는지 확인합니다.
pip도 사용할 수 있지만 기존 Conda 환경 위에 패키지와 의존성을 설치하며 Conda 패키지의 의존성 제약을 함께 해결하지 않습니다.
GPU 사용 확인
다음 코드는 CPU와 GPU에서 5,000×5,000 행렬 곱 시간을 측정합니다. GPU를 예열하고 synchronize로 연산 완료를 기다립니다. 행렬 곱의 측정 배율이 실제 모델 학습의 속도 향상과 같지는 않습니다.
import torch
import time
import logging
logger = logging.getLogger(__name__)
A_cpu = torch.randn(5000, 5000)
B_cpu = torch.randn(5000, 5000)
start_time = time.time()
C_cpu = torch.matmul(A_cpu, B_cpu)
cpu_time = time.time() - start_time
logger.warning(f"CPU execution time: {cpu_time:.4f} seconds")
if torch.cuda.is_available():
A_gpu = torch.randn(5000, 5000, device='cuda')
B_gpu = torch.randn(5000, 5000, device='cuda')
# Warm-up run to initialize the GPU
_ = torch.matmul(A_gpu, B_gpu)
torch.cuda.synchronize()
# Actual benchmark
start_time = time.time()
C_gpu = torch.matmul(A_gpu, B_gpu)
torch.cuda.synchronize() # Waiting for GPU computation to finish
gpu_time = time.time() - start_time
logger.warning(f"GPU execution time: {gpu_time:.4f} seconds")
logger.warning(f"GPU speedup: {cpu_time/gpu_time:.2f}x faster")
JupyterLab의 파일 브라우저에서 + > Terminal을 열고 다음 명령으로 장치 사용률, 메모리와 실행 중인 프로세스를 볼 수 있습니다.
watch -n0.2 nvidia-smi
별도 모델 환경을 사용하는 sidecar
다른 저장소에서 만든 모델을 추론하면 현재 저장소와 모델의 의존성을 함께 해결하는 과정에서 버전 충돌이 생길 수 있습니다. ModelInput의 use_sidecar=True는 모델 어댑터와 해당 Python 환경을 별도 컨테이너에 로드합니다. sidecar_resources로 컨테이너의 GPU, CPU 및 메모리를 요청합니다.
경량 @transform.using에서 sidecar를 사용하려면 palantir_models 0.2010.0 이상이 필요합니다. 다음 예제의 경로는 실제 입력, 모델과 출력 리소스로 바꿉니다. 모델 API는 df_out이라는 Pandas 출력을 제공해야 합니다.
from transforms.api import transform, Input, Output, configure, LightweightInput, LightweightOutput
from palantir_models.transforms import ModelInput
from palantir_models import ModelAdapter
# Using use_sidecar=True with @transform.using requires palantir_models version 0.2010.0 or higher.
@transform.using(
inference_output=Output("path_to_output"),
inference_input=Input("path_to_input"),
model=ModelInput(
"path_to_model",
use_sidecar=True,
sidecar_resources={"gpus": 1, "cpus": 3.4, "memory_gb": 16}
),
)
def compute(
inference_output: LightweightOutput,
inference_input: LightweightInput,
model: ModelAdapter
):
inference_results = model.transform(inference_input)
inference = inference_results.df_out
inference_output.write_pandas(inference)
sidecar의 cpus와 memory_gb는 수치, gpus는 정수이며 sidecar_resources는 use_sidecar=True인 경우에만 지정합니다. 모델 환경을 분리하면 추론 저장소에서 어댑터 의존성을 다른 버전으로 다시 해결하는 문제를 피할 수 있습니다.