Ubuntu 22.04 노트북에서 NVIDIA GeForce RTX 5050 Laptop GPU를 이용해 TensorFlow와 YOLO11을 실행하려고 하면 기존 RTX 30, RTX 40 시리즈와는 조금 다른 문제가 발생합니다.
RTX 5050은 NVIDIA Blackwell 계열이며 CUDA Compute Capability가 12.0, 즉 sm_120입니다.
일반적인 Python 가상환경에 TensorFlow를 설치하면 다음 단계까지는 정상적으로 진행될 수 있습니다.
import tensorflow as tf
print(tf.config.list_physical_devices('GPU'))
GPU가 검색되거나 CUDA 라이브러리가 로딩되는 것처럼 보여도 실제 Conv2D, MatMul, 모델 학습 같은 GPU 연산에서 실패할 수 있습니다.
이 문제를 해결하기 위해 호스트 Ubuntu에 TensorFlow와 CUDA를 직접 설치하지 않고 Docker를 사용합니다.
구성 목표는 다음과 같습니다.
- Ubuntu 22.04 호스트에는 NVIDIA 드라이버만 설치
- Docker Engine 설치
- NVIDIA Container Toolkit 설치
- CUDA Toolkit은 Docker 안에서 관리
- CUDA 12.8.1 사용
- cuDNN 9.8 사용
- Clang 20 이상 사용
- RTX 5050의
sm_120을 대상으로 TensorFlow 직접 소스 빌드 - 빌드된 TensorFlow wheel을 별도 Runtime 이미지에 설치
- TensorFlow와 YOLO 환경을 서로 다른 Docker 이미지로 분리
- 데이터셋, Notebook, 학습 결과는 호스트 디렉터리에 보존
- JupyterLab을 Docker 컨테이너 안에서 실행
이번 글의 핵심은 단순히 TensorFlow 공식 Docker 이미지를 실행하는 것이 아닙니다.
RTX 5050 sm_120을 명시하여 TensorFlow 자체를 CUDA 12.8 + cuDNN 9.8 환경에서 다시 컴파일하는 것이 핵심입니다.
1. 최종 구성
전체 구조는 다음과 같습니다.
Ubuntu 22.04 Host
│
├── NVIDIA Driver 595-open
│
├── Docker Engine
│
├── NVIDIA Container Toolkit
│
└── ~/ai_docker
│
├── docker
│ ├── tensorflow-sm120
│ │ └── Dockerfile
│ │
│ └── yolo
│ └── Dockerfile
│
├── notebooks
│ ├── train_tensorflow_track_detection_docker.ipynb
│ └── train_yolo11n_object_detection_docker.ipynb
│
├── dataset
│ ├── dl_images
│ └── yolo_images
│
├── models
├── runs
├── wheelhouse
└── .cuda_cache
TensorFlow와 YOLO는 각각 별도의 Docker 이미지로 운영합니다.
tf-sm120
CUDA 12.8.1
cuDNN 9.8
TensorFlow source build
compute_120 / sm_120
JupyterLab
yolo-sm120
CUDA 12.8
PyTorch CUDA 12.8
Ultralytics
YOLO11
JupyterLab
이렇게 구성하면 TensorFlow와 PyTorch의 CUDA 라이브러리가 서로 충돌하지 않습니다.
2. RTX 5050과 기존 TensorFlow wheel의 문제
현재 TensorFlow 공식 소스 빌드 호환표에서 TensorFlow 2.21.0 공식 GPU 패키지는 다음 환경을 기준으로 합니다.
TensorFlow : 2.21.0
CUDA : 12.5
cuDNN : 9.3
Compiler : Clang 18.1.8
Bazel : 7.4.1
즉 공식 TensorFlow wheel이 RTX 5050의 sm_120을 직접 목표로 만들어진 환경과는 차이가 있습니다.
RTX 50 계열 Blackwell 관련 TensorFlow는 아래와 같이 사용자 빌드 구성이 가능합니다.
CUDA : 12.8.x
cuDNN : 9.8.0
Compute Capability: 12.0
Hermetic target : compute_120
Compiler : 최신 LLVM/Clang
TensorFlow : source build
단지 위의 조합은 TensorFlow의 공식 지원 조합이 아니라 커뮤니티에서 검증된 커스텀 빌드 방식입니다.
따라서 일반 pip install tensorflow를 설치하면 정상적으로 동작하지 않을 가능성이 높기 때문에 TensorFlow 소스를 직접 컴파일합니다.
3. CUDA 12.8과 cuDNN 9.8을 사용하는 이유
NVIDIA cuDNN 9.8 공식 Support Matrix를 보면 CUDA 12.8 환경에서 Compute Capability 12.0과 NVIDIA Blackwell을 지원합니다.
여기에서 사용할 NVIDIA 공식 Docker 이미지는 다음가 같습니다.
nvidia/cuda:12.8.1-cudnn-devel-ubuntu22.04
이 이미지에는 실제로 다음 버전이 포함되어 있습니다.
CUDA_VERSION=12.8.1
NV_CUDNN_VERSION=9.8.0.87-1
즉 별도로 CUDA Toolkit과 cuDNN을 하나씩 설치할 필요가 없습니다.
이 방식의 장점은 호스트 Ubuntu의 CUDA 설치 상태와 완전히 분리할 수 있다는 것입니다.
호스트에는 NVIDIA Driver만 있으면 됩니다.
4. 호스트 NVIDIA 드라이버 확인
아래의 명령어를 실행하여 추천 드라이버를 확인합니다.
ubuntu-drivers devices

현재 시스템에서는 다음 드라이버가 추천되었습니다.
nvidia-driver-595-open - distro non-free recommended
아래의 명령을 실행하여 nvidia-driver-595-open 드라이브를 설치합니다.
sudo apt update
sudo apt install nvidia-driver-595-open
sudo reboot
드라이버 설치가 끝났다면 먼저 다음 명령을 실행합니다.
nvidia-smi

RTX 5050이 표시되어야 합니다.
예를 들면 다음과 같습니다.
NVIDIA GeForce RTX 5050 Laptop GPU
커널 드라이버도 확인합니다.
lspci -k -s 01:00.0

정상적인 경우 다음 항목이 있어야 합니다.
Kernel driver in use: nvidia
이전의
UNCLAIMED
상태가 남아 있으면 Docker 설치를 진행하기 전에 NVIDIA 드라이버 문제부터 해결해야 합니다.
5. 호스트에는 CUDA Toolkit을 설치하지 않는다
지금 설치 방식에서는 Ubuntu 호스트에 아래의 패키지를 설치할 필요가 없습니다.
cuda-toolkit
libcudnn
nvcc
tensorflow
pytorch
다음 명령이 실패해도 상관없습니다.
nvcc --version

CUDA Toolkit과 cuDNN은 Docker 이미지 내부에 존재합니다.
구조는 다음과 같습니다.
Host Ubuntu
NVIDIA Driver
Docker Container
CUDA Toolkit
cuDNN
TensorFlow
PyTorch
Docker에서 GPU를 사용할 때 중요한 것은 호스트 NVIDIA 드라이버와 NVIDIA Container Toolkit입니다.
6. Docker가 필요한 이유
Docker는 프로그램 실행 환경을 하나의 독립된 공간으로 만드는 도구입니다.
예를 들어 Ubuntu에 직접 다음 프로그램을 모두 설치한다고 생각해 보겠습니다.
ROS 2
TensorFlow
PyTorch
CUDA
cuDNN
OpenCV
YOLO
Jupyter
각 프로그램이 요구하는 버전이 달라지면 충돌이 발생할 수 있습니다.
Docker를 사용하면 다음처럼 분리할 수 있습니다.
Ubuntu
│
├── ROS 2
│
├── TensorFlow Docker
│
└── YOLO Docker
TensorFlow 환경이 문제가 생겨도 ROS 2 환경에는 영향을 주지 않습니다.
이것이 이번 강의에서 Docker를 사용하는 가장 큰 이유입니다.
7. Docker Engine 설치
Ubuntu 22.04는 Docker Engine 공식 지원 대상입니다.
먼저 기존 충돌 패키지가 있다면 제거합니다.
sudo apt remove -y \
docker.io \
docker-compose \
docker-compose-v2 \
docker-doc \
docker-buildx \
podman-docker \
containerd \
runc

패키지가 없다는 메시지가 나와도 문제없습니다.
Docker 저장소 키를 등록합니다.
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL \
https://download.docker.com/linux/ubuntu/gpg \
-o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc





Docker 저장소를 추가합니다.
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

패키지 목록을 갱신합니다.
sudo apt update

Docker를 설치합니다.
sudo apt install -y \
docker-ce \
docker-ce-cli \
containerd.io \
docker-buildx-plugin \
docker-compose-plugin

Docker 상태를 확인합니다.
sudo systemctl status docker

간단한 테스트를 실행합니다.
sudo docker run --rm hello-world

8. sudo 없이 Docker 사용하기
개발 PC에서는 매번 sudo docker를 입력하지 않도록 현재 사용자를 Docker 그룹에 추가할 수 있습니다.
sudo usermod -aG docker $USER
현재 터미널에서 그룹을 다시 적용합니다.
newgrp docker
확인합니다.
docker ps

위의 결과에서 헤더만 나오고 아래 내용이 없는 것은 Docker 명령이 정상 실행되고, 현재 사용자가 sudo 없이 Docker에 접근 가능하며 Docker daemon도 정상 동작 중이라는 것입니다. 단지 현재 실행 중인 컨테이너가 0개라는 의미입니다.
Docker 그룹은 높은 시스템 권한을 가질 수 있으므로 여러 사용자가 함께 사용하는 서버에서는 권한 정책을 별도로 관리하는 것이 좋습니다.
9. NVIDIA Container Toolkit 설치
일반 Docker만 설치하면 컨테이너가 NVIDIA GPU를 사용할 수 없습니다.
NVIDIA Container Toolkit을 설치해야 합니다.
필수 패키지를 설치합니다.
sudo apt-get update
sudo apt-get install -y \
ca-certificates \
curl \
gnupg2


NVIDIA 저장소 키를 추가합니다.
curl -fsSL \
https://nvidia.github.io/libnvidia-container/gpgkey \
| sudo gpg --dearmor \
-o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

저장소를 추가합니다.
curl -s -L \
https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
| sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
| sudo tee \
/etc/apt/sources.list.d/nvidia-container-toolkit.list

패키지를 설치합니다.
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit


Docker Runtime을 구성합니다.
sudo nvidia-ctk runtime configure --runtime=docker

Docker를 다시 시작합니다.
sudo systemctl restart docker

이 과정은 현재 NVIDIA에서 제공하는 Container Toolkit 공식 설치 방식입니다.
10. Docker에서 RTX 5050 접근 시험
이 단계는 반드시 확인합니다.
docker run --rm \
--gpus all \
nvidia/cuda:12.8.1-base-ubuntu22.04 \
nvidia-smi


1. docker run : Docker 이미지를 기반으로 새 컨테이너를 생성하고 바로 실행하라는 명령입니다.
2. –rm : 컨테이너에서 실행한 프로그램이 끝나면 컨테이너 자체를 자동 삭제합니다.
3. –gpus all : Docker 컨테이너에서 호스트 PC에 설치되어 있는 모든 NVIDIA GPU를 사용할 수 있도록 연결합니다.
4. nvidia/cuda:12.8.1-base-ubuntu22.04 : nvidia/cuda는 NVIDIA에서 제공하는 CUDA Docker 이미지입니다. 즉 일반 Ubuntu가 아니라 CUDA 관련 환경이 포함된 NVIDIA 공식 컨테이너 이미지입니다. 12.8.1은 컨테이너에서 사용하는 CUDA Toolkit 계열 버전입니다. base는 CUDA Docker 이미지 중에서 가장 최소한의 기본 실행 환경에 가까운 이미지입니다. ubuntu22.04는 컨테이너 내부 Linux 사용자 공간이 Ubuntu 22.04 기반이라는 의미입니다.
5. nvidia-smi : 컨테이너가 시작된 뒤 실행할 명령입니다.
요약하면 Docker에게 CUDA 12.8.1 Ubuntu 22.04 컨테이너를 만들고, 모든 NVIDIA GPU를 연결한 뒤 nvidia-smi를 실행하라고 명령한 것입니다.
컨테이너 안에서도 다음 GPU가 보여야 합니다.
NVIDIA GeForce RTX 5050 Laptop GPU
이 명령이 실패하면 TensorFlow를 빌드하기 전에 Docker GPU Runtime부터 해결해야 합니다.
이 단계가 정상이라면 다음 구조가 만들어진 것입니다.
Ubuntu NVIDIA Driver
↓
NVIDIA Container Toolkit
↓
Docker
↓
RTX 5050
11. 프로젝트 디렉터리 만들기
작업용 디렉터리를 생성합니다.
mkdir -p ~/ai_docker/docker/tensorflow-sm120
mkdir -p ~/ai_docker/docker/yolo
mkdir -p ~/ai_docker/notebooks
mkdir -p ~/ai_docker/dataset/dl_images
mkdir -p ~/ai_docker/dataset/yolo_images
mkdir -p ~/ai_docker/models
mkdir -p ~/ai_docker/runs
mkdir -p ~/ai_docker/wheelhouse
mkdir -p ~/ai_docker/.cuda_cache
프로젝트 디렉터리로 이동합니다.
cd ~/ai_docker
최종 구조는 다음과 같습니다.
~/ai_docker
├── docker
│ ├── tensorflow-sm120
│ └── yolo
├── notebooks
├── dataset
│ ├── dl_images
│ └── yolo_images
├── models
├── runs
├── wheelhouse
└── .cuda_cache

12. Jupyter Notebook 파일 복사
TensorFlow Notebook을 다음 위치에 둡니다.
~/ai_docker/notebooks/
train_tensorflow_track_detection_on_custom_dataset.ipynb
YOLO Notebook도 같은 위치에 둡니다.
~/ai_docker/notebooks/
train_yolo11n_object_detection_on_custom_dataset.ipynb
최종적으로 다음과 같이 됩니다.
~/ai_docker/notebooks
├── train_tensorflow_track_detection_on_custom_dataset.ipynb
├── train_yolo11n_object_detection_on_custom_dataset.ipynb

Docker에서는 호스트의
~/ai_docker
전체를 컨테이너의
/workspace
에 연결할 것입니다.
따라서 컨테이너에서 보는 구조는 다음과 같습니다.
/workspace
├── notebooks
├── dataset
├── models
└── runs
13. Docker의 /workspace 이해하기
이후 Docker를 실행할 때 다음 옵션을 사용합니다.
-v ~/ai_docker:/workspace
이 명령은 매우 중요합니다.
Ubuntu의
~/ai_docker
폴더를 Docker 안에서는
/workspace
라는 이름으로 보겠다는 의미입니다.
예를 들어 Ubuntu의 다음 파일은
~/ai_docker/notebooks/test.ipynb
Docker 안에서는 다음 위치에서 보입니다.
/workspace/notebooks/test.ipynb
학생들이 Docker에서 가장 자주 혼동하는 부분 중 하나가 파일 경로이므로 이 개념을 기억하는 것이 좋습니다.
14. TensorFlow 환경의 기본 구조
RTX 5050에서는 일반 TensorFlow 패키지를 설치하는 대신 GPU에 맞게 직접 TensorFlow를 만들어 사용합니다.
우리가 만들 Docker 환경은 다음과 같습니다.
Ubuntu 22.04
↓
CUDA 12.8
↓
cuDNN 9.8
↓
Clang 20 이상
↓
TensorFlow Source Build
↓
RTX 5050 sm_120
여기서 각각의 프로그램 내부를 이해할 필요는 없습니다.
역할만 다음처럼 이해하면 됩니다.
CUDA
NVIDIA GPU를 사용하기 위한 개발 환경
cuDNN
딥러닝 연산을 빠르게 실행하는 NVIDIA 라이브러리
Clang
TensorFlow 소스를 컴파일하는 프로그램
TensorFlow
딥러닝 프로그램
sm_120
RTX 5050이 사용하는 GPU 코드 종류
14. TensorFlow Dockerfile 만들기
다음 위치에 Dockerfile을 만듭니다.
nano \
~/ai_docker/docker/tensorflow-sm120/Dockerfile

Dockerfile은 Docker 환경을 만드는 설치 설명서라고 생각하면 됩니다.
이번 수업에서는 아래 내용을 그대로 복사해서 사용합니다.
FROM nvidia/cuda:12.8.1-cudnn-devel-ubuntu22.04
ENV DEBIAN_FRONTEND=noninteractive
ENV CUDA_HOME=/usr/local/cuda
ENV PATH=/usr/local/cuda/bin:${PATH}
RUN apt-get update && \
apt-get install -y \
build-essential \
ca-certificates \
curl \
git \
gnupg \
python3 \
python3-dev \
python3-pip \
unzip \
wget \
zip
RUN curl -fsSL \
https://apt.llvm.org/llvm-snapshot.gpg.key \
| gpg --dearmor \
-o /usr/share/keyrings/llvm.gpg
RUN echo \
"deb [signed-by=/usr/share/keyrings/llvm.gpg] \
http://apt.llvm.org/jammy/ \
llvm-toolchain-jammy-22 main" \
> /etc/apt/sources.list.d/llvm.list
RUN apt-get update && \
apt-get install -y \
clang-22 \
lld-22
RUN ln -sf \
/usr/bin/clang-22 \
/usr/local/bin/clang
RUN ln -sf \
/usr/bin/clang++-22 \
/usr/local/bin/clang++
RUN wget \
https://github.com/bazelbuild/bazelisk/releases/download/v1.29.0/bazelisk-linux-amd64 \
-O /usr/local/bin/bazel
RUN chmod +x \
/usr/local/bin/bazel
RUN python3 -m pip install \
--upgrade \
pip \
setuptools \
wheel \
numpy
WORKDIR /opt
RUN git clone \
https://github.com/tensorflow/tensorflow.git
WORKDIR /opt/tensorflow
RUN git checkout 85ce1cf
ENV PYTHON_BIN_PATH=/usr/bin/python3
ENV USE_DEFAULT_PYTHON_LIB_PATH=1
ENV TF_NEED_CUDA=1
ENV TF_NEED_ROCM=0
ENV TF_CUDA_CLANG=1
ENV TF_NEED_CLANG=1
ENV CC=/usr/bin/clang-22
ENV CXX=/usr/bin/clang++-22
ENV HERMETIC_CUDA_VERSION=12.8.1
ENV HERMETIC_CUDNN_VERSION=9.8.0
ENV HERMETIC_CUDA_COMPUTE_CAPABILITIES=compute_120
RUN python3 configure.py
RUN bazel build \
//tensorflow/tools/pip_package:wheel \
--repo_env=USE_PYWRAP_RULES=1 \
--repo_env=WHEEL_NAME=tensorflow \
--repo_env=HERMETIC_CUDA_COMPUTE_CAPABILITIES=sm_120 \
--config=cuda_nvcc \
--config=cuda_wheel \
--config=opt \
--jobs=2 \
--local_ram_resources=6144 \
--verbose_failures
RUN python3 -m pip install \
bazel-bin/tensorflow/tools/pip_package/wheel_house/*.whl
RUN python3 -m pip install \
opencv-python-headless \
matplotlib \
pillow \
tqdm \
pandas \
jupyterlab \
ipykernel
WORKDIR /workspace
EXPOSE 8888
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root"]

파일을 저장합니다.
Nano에서는 다음 키를 사용합니다.
Ctrl + O
Enter
Ctrl + X
16. TensorFlow Dockerfile 분석
Dockerfile은 NVIDIA CUDA 12.8.1 환경에서 TensorFlow를 소스 코드부터 직접 빌드하고, GPU를 사용할 수 있는 Python/JupyterLab 개발 환경까지 만드는 구성입니다.
특히 sm_120 아키텍처를 대상으로 TensorFlow를 빌드하도록 설정되어 있어 RTX 50 시리즈와 같은 최신 NVIDIA GPU 환경을 준비할 때 사용할 수 있습니다.
1) CUDA + cuDNN 기반 이미지 사용
FROM nvidia/cuda:12.8.1-cudnn-devel-ubuntu22.04
Docker 환경의 기본 이미지를 지정합니다.
이 이미지는 다음 환경을 포함합니다.
- Ubuntu 22.04
- CUDA 12.8.1
- cuDNN
- CUDA 개발 도구
devel 이미지이기 때문에 단순 실행뿐만 아니라 CUDA 프로그램이나 TensorFlow를 직접 컴파일할 수 있습니다.
2) 설치 과정에서 사용자 입력 비활성화
ENV DEBIAN_FRONTEND=noninteractive
Docker 이미지를 만드는 과정에서 패키지 설치 중 질문이 나타나지 않도록 설정합니다.
자동으로 Docker 이미지를 만들 때 많이 사용하는 설정입니다.
3) CUDA 환경 변수 설정
ENV CUDA_HOME=/usr/local/cuda
ENV PATH=/usr/local/cuda/bin:${PATH}
CUDA 설치 위치를 시스템에 알려줍니다.
이를 통해 다음과 같은 CUDA 명령을 사용할 수 있습니다.
nvcc
즉, TensorFlow를 빌드할 때 CUDA Compiler를 쉽게 찾을 수 있도록 하는 설정입니다.
4) 기본 개발 도구 설치
RUN apt-get update && \
apt-get install -y \
build-essential \
ca-certificates \
curl \
git \
gnupg \
python3 \
python3-dev \
python3-pip \
unzip \
wget \
zip
TensorFlow를 소스에서 빌드하기 위해 필요한 기본 프로그램을 설치합니다.
주요 패키지는 다음과 같습니다.
build-essential: C/C++ 컴파일 도구git: TensorFlow 소스 다운로드python3: Python 실행python3-dev: Python 개발 헤더python3-pip: Python 패키지 설치curl: 인터넷 파일 다운로드
5) LLVM 저장소 키 추가
RUN curl -fsSL \
https://apt.llvm.org/llvm-snapshot.gpg.key \
| gpg --dearmor \
-o /usr/share/keyrings/llvm.gpg
LLVM 공식 저장소의 패키지를 안전하게 설치하기 위해 GPG 키를 등록합니다.
이후 설치할 clang-22 컴파일러를 위한 준비 과정입니다.
6) LLVM 22 저장소 추가
RUN echo \
"deb [signed-by=/usr/share/keyrings/llvm.gpg] \
http://apt.llvm.org/jammy/ \
llvm-toolchain-jammy-22 main" \
> /etc/apt/sources.list.d/llvm.list
Ubuntu 기본 저장소가 아닌 LLVM 공식 저장소에서 최신 Clang 22를 설치할 수 있도록 저장소를 추가합니다.
7) Clang 22와 LLD 설치
RUN apt-get update && \
apt-get install -y \
clang-22 \
lld-22
TensorFlow를 빌드할 때 사용할 컴파일러를 설치합니다.
clang-22: C/C++ 컴파일러lld-22: LLVM Linker
TensorFlow CUDA 빌드에서 Clang을 사용하도록 설정하기 위한 과정입니다.
8) Clang 명령 연결
RUN ln -sf \
/usr/bin/clang-22 \
/usr/local/bin/clang
RUN ln -sf \
/usr/bin/clang++-22 \
/usr/local/bin/clang++
다음 명령을 실행했을 때:
clang
clang++
실제로는 Clang 22가 실행되도록 심볼릭 링크를 생성합니다.
9) Bazelisk 설치
RUN w_get \
https://github.com/bazelbuild/bazelisk/releases/download/v1.29.0/bazelisk-linux-amd64 \
-O /usr/local/bin/bazel
TensorFlow는 일반적인 make가 아니라 Bazel 빌드 시스템을 사용합니다.
여기서는 Bazel을 직접 설치하는 대신 Bazelisk를 사용합니다.
Bazelisk는 프로젝트에 적절한 Bazel 버전을 선택해 실행해주는 도구입니다.
10) Bazel 실행 권한 부여
RUN chmod +x \
/usr/local/bin/bazel
다운로드한 Bazelisk 파일을 실제 명령어로 실행할 수 있도록 실행 권한을 추가합니다.
11) Python 기본 패키지 설치
RUN python3 -m pip install \
--upgrade \
pip \
setuptools \
wheel \
numpy
TensorFlow 빌드와 Python 패키지 생성을 위해 필요한 기본 Python 도구를 설치합니다.
특히 wheel은 TensorFlow 설치 패키지인 .whl 파일을 만들 때 사용됩니다.
12) TensorFlow 소스 코드 다운로드
WORKDIR /opt
RUN git clone \
https://github.com/tensorflow/tensorflow.git
TensorFlow 공식 GitHub 저장소에서 전체 소스 코드를 다운로드합니다.
즉, PyPI에서 TensorFlow를 설치하는 것이 아니라 직접 컴파일하기 위한 것입니다.
13) TensorFlow 특정 소스 버전 선택
WORKDIR /opt/tensorflow
RUN git checkout 85ce1cf
TensorFlow Git 저장소에서 특정 Commit 상태로 이동합니다.
이렇게 하면 빌드할 때마다 동일한 TensorFlow 소스를 사용할 수 있어 재현성이 높아집니다.
14) TensorFlow Python 환경 설정
ENV PYTHON_BIN_PATH=/usr/bin/python3
ENV USE_DEFAULT_PYTHON_LIB_PATH=1
TensorFlow를 빌드할 때 사용할 Python 실행 파일을 지정합니다.
여기서는 Ubuntu에 설치된 Python 3를 사용합니다.
15) CUDA 빌드 활성화
ENV TF_NEED_CUDA=1
ENV TF_NEED_ROCM=0
TensorFlow를 NVIDIA CUDA 기반으로 빌드하도록 설정합니다.
TF_NEED_CUDA=1
은 NVIDIA GPU 지원을 활성화한다는 의미입니다.
반면:
ENV TF_NEED_ROCM=0
은 AMD GPU용 ROCm은 사용하지 않겠다는 의미입니다.
16) Clang 컴파일러 사용 설정
ENV TF_CUDA_CLANG=1
ENV TF_NEED_CLANG=1
TensorFlow 및 CUDA 빌드에 Clang을 사용하도록 설정합니다.
17) Clang 22 직접 지정
ENV CC=/usr/bin/clang-22
ENV CXX=/usr/bin/clang++-22
C 컴파일러는:
clang-22
C++ 컴파일러는:
clang++-22
를 사용하도록 지정합니다.
18) CUDA와 cuDNN 버전 지정
ENV HERMETIC_CUDA_VERSION=12.8.1
ENV HERMETIC_CUDNN_VERSION=9.8.0
TensorFlow의 Hermetic CUDA 빌드에 사용할 CUDA와 cuDNN 버전을 지정합니다.
여기서는:
CUDA : 12.8.1
cuDNN : 9.8.0
으로 설정합니다.
19) GPU Compute Capability 설정
ENV HERMETIC_CUDA_COMPUTE_CAPABILITIES=compute_120
TensorFlow를 어떤 NVIDIA GPU 아키텍처에 맞춰 빌드할지 설정합니다.
여기서는:
Compute Capability 12.0
즉:
sm_120
을 대상으로 합니다.
20) TensorFlow 빌드 환경 설정
RUN python3 configure.py
TensorFlow를 빌드하기 전에 Python, CUDA, Compiler 등의 환경을 확인하고 빌드 설정을 생성합니다.
앞에서 ENV로 지정한 환경 변수들이 이 과정에서 사용됩니다.
21) TensorFlow Wheel 빌드
RUN bazel build \
//tensorflow/tools/pip_package:wheel \
--repo_env=USE_PYWRAP_RULES=1 \
--repo_env=WHEEL_NAME=tensorflow \
--repo_env=HERMETIC_CUDA_COMPUTE_CAPABILITIES=sm_120 \
--config=cuda_nvcc \
--config=cuda_wheel \
--config=opt \
--jobs=2 \
--local_ram_resources=6144 \
--verbose_failures
Dockerfile에서 가장 핵심적인 부분입니다.
TensorFlow 전체 소스를 CUDA GPU용으로 직접 컴파일하여 Python에서 설치할 수 있는 Wheel 파일을 생성합니다.
주요 설정은 다음과 같습니다.
sm_120
GPU 아키텍처 대상으로 빌드합니다.
--config=cuda_nvcc
CUDA NVCC 기반 빌드를 활성화합니다.
--config=cuda_wheel
CUDA를 포함한 TensorFlow Wheel 패키지를 생성합니다.
--jobs=2
동시에 실행할 빌드 작업을 2개로 제한합니다.
--local_ram_resources=6144
Bazel이 사용할 메모리를 약 6GB 수준으로 제한합니다.
TensorFlow 빌드는 CPU와 메모리를 많이 사용하기 때문에 시스템 사양에 맞춰 이 값을 조정할 수 있습니다.
22) 직접 만든 TensorFlow 설치
RUN python3 -m pip install \
bazel-bin/tensorflow/tools/pip_package/wheel_house/*.whl
앞에서 소스 코드로 직접 빌드한 TensorFlow Wheel 파일을 Python 환경에 설치합니다.
즉:
TensorFlow 소스
↓
Bazel Compile
↓
tensorflow-xxxx.whl
↓
pip install
↓
TensorFlow 설치 완료
의 과정입니다.
23) AI 개발용 Python 라이브러리 설치
RUN python3 -m pip install \
opencv-python-headless \
matplotlib \
pillow \
tqdm \
pandas \
jupyterlab \
ipykernel
TensorFlow 외에 AI 개발과 이미지 처리, 데이터 분석에 필요한 라이브러리를 설치합니다.
주요 패키지는 다음과 같습니다.
opencv-python-headless: 이미지 및 영상 처리matplotlib: 그래프 출력pillow: 이미지 처리tqdm: 작업 진행률 표시pandas: 데이터 처리jupyterlab: 웹 기반 Python 개발 환경ipykernel: Jupyter에서 Python 실행
24) 작업 디렉터리 지정
WORKDIR /workspace
Docker 컨테이너가 실행되었을 때 기본 작업 위치를:
/workspace
로 지정합니다.
앞으로 AI 프로젝트, 학습 데이터, Python 코드 등을 이 위치에서 관리할 수 있습니다.
25) JupyterLab 포트 설정
EXPOSE 8888
JupyterLab이 사용할 8888 포트를 Docker 이미지에서 사용하도록 표시합니다.
Docker 실행 시에는 예를 들어 다음과 같이 연결할 수 있습니다.
-p 8888:8888
26) 컨테이너 시작 시 JupyterLab 자동 실행
CMD ["jupyter", "lab", "--ip=0.0.0.0", "--port=8888", "--no-browser", "--allow-root"]
Docker 컨테이너가 실행되면 자동으로 JupyterLab을 시작합니다.
주요 옵션은 다음과 같습니다.
--ip=0.0.0.0
컨테이너 외부에서도 접속할 수 있도록 설정합니다.
--port=8888
JupyterLab 포트를 8888로 사용합니다.
--no-browser
컨테이너 내부에서 웹 브라우저를 자동 실행하지 않습니다.
--allow-root
Docker 컨테이너의 root 사용자로 JupyterLab 실행을 허용합니다.
27) 전체 동작 구조
전체 Dockerfile의 동작 흐름을 간단히 정리하면 다음과 같습니다.
NVIDIA CUDA 12.8.1 + cuDNN
↓
Ubuntu 22.04
↓
Python / 개발 도구 설치
↓
Clang 22 설치
↓
Bazelisk 설치
↓
TensorFlow Source 다운로드
↓
CUDA 활성화
↓
sm_120 GPU 대상으로 TensorFlow 빌드
↓
TensorFlow Wheel 생성
↓
TensorFlow 설치
↓
OpenCV / Pandas / Pillow 등 설치
↓
JupyterLab 실행
17. TensorFlow Docker 이미지 만들기
프로젝트 폴더로 이동합니다.
cd ~/ai_docker
다음 명령을 실행합니다.
docker build -t tensorflow-sm120 -f docker/tensorflow-sm120/Dockerfile .






각 부분의 의미는 다음과 같습니다.
docker build
Docker 이미지를 만든다.
-t tensorflow-sm120
이미지 이름을 tensorflow-sm120으로 한다.
-f docker/tensorflow/Dockerfile
사용할 Dockerfile 위치를 지정한다.
.
현재 폴더를 기준으로 작업한다.
TensorFlow는 소스에서 직접 컴파일하기 때문에 많은 파일을 처리합니다.
중간에 다양한 컴파일 메시지가 출력되는 것은 정상입니다.
18. 빌드 중 메모리 부족이 발생하는 경우
노트북의 RAM이 많지 않으면 TensorFlow 빌드 중 메모리가 부족할 수 있습니다.
Dockerfile에는 다음 설정이 들어 있습니다.
--jobs=2
--local_ram_resources=6144
--jobs=2는 동시에 너무 많은 컴파일 작업을 실행하지 않도록 제한하는 설정입니다.
메모리가 부족하다면 다음 부분을 찾습니다.
--local_ram_resources=6144
그리고 다음과 같이 낮출 수 있습니다.
--local_ram_resources=4096
컴파일 중 노트북이 지나치게 느려진다면 다음 프로그램을 종료하는 것도 도움이 됩니다.
웹 브라우저의 많은 탭
VS Code의 불필요한 프로젝트
다른 Docker 컨테이너
가상 머신
다른 AI 프로그램
19. TensorFlow Docker 이미지 확인
빌드가 완료되면 다음 명령을 실행합니다.
docker images

목록에 다음 이미지가 있으면 됩니다.
tensorflow-sm120
예를 들면 다음과 같습니다.
REPOSITORY TAG
tensorflow-sm120 latest
이제 TensorFlow 실행 환경이 만들어진 것입니다.
20. TensorFlow Docker 실행
다음 명령을 실행합니다.
docker run --rm -it \
--gpus all \
--name tensorflow-sm120 \
--shm-size=4g \
-p 8888:8888 \
-v ~/ai_docker:/workspace \
tensorflow-sm120


각 옵션의 의미는 다음과 같습니다.
--gpus all
Docker가 NVIDIA GPU를 사용한다.
--name tensorflow-sm120
실행 중인 Docker 이름을 지정한다.
--shm-size=4g
TensorFlow가 사용할 공유 메모리를 늘린다.
-p 8888:8888
JupyterLab 접속 포트를 연결한다.
-v ~/ai_docker:/workspace
Ubuntu 폴더와 Docker 폴더를 연결한다.
잠시 후 JupyterLab 주소가 출력됩니다.
예를 들면 다음과 같습니다.
http://127.0.0.1:8888/lab?token=0a9e0a47a7c3a2b70fa859e3e5ded2c83003f02e33e5f8c5
이 주소를 웹 브라우저에 입력합니다.

20. Docker 안에서 GPU 확인
새 터미널을 하나 엽니다.
실행 중인 TensorFlow Docker에 들어갑니다.
docker exec -it tensorflow-sm120 bash

먼저 NVIDIA GPU를 확인합니다.
nvidia-smi

다음 GPU가 표시되는지 확인합니다.
NVIDIA GeForce RTX 5050 Laptop GPU
21. TensorFlow가 GPU를 찾는지 확인
Docker 안에서 다음 명령을 실행합니다.
python3 -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"
정상적인 경우 다음과 비슷하게 출력됩니다.
[
PhysicalDevice(
name='/physical_device:GPU:0',
device_type='GPU'
)
]

여기까지만 확인하고 끝내면 안 됩니다.
기존 Python 가상환경에서는 GPU가 보이면서 실제 계산은 실패할 수 있었기 때문입니다.
따라서 실제 계산을 한 번 실행합니다.
22. TensorFlow GPU 실제 계산 확인
Docker 안에서 다음 명령을 그대로 실행합니다.
python3 - <<'PY'
import tensorflow as tf
print("TensorFlow version:")
print(tf.__version__)
print("GPU:")
print(
tf.config.list_physical_devices('GPU')
)
with tf.device('/GPU:0'):
a = tf.random.normal(
[2048, 2048]
)
b = tf.random.normal(
[2048, 2048]
)
c = tf.matmul(a, b)
print(
"Result:",
tf.reduce_sum(c).numpy()
)
print(
"TensorFlow GPU TEST OK"
)
PY

마지막에 다음 문장이 표시되면 됩니다.
TensorFlow GPU TEST OK
이 테스트는 행렬 계산을 실제 NVIDIA GPU에서 실행하는 과정입니다.
23. 다른 터미널에서 GPU 사용량 보기
Ubuntu에서 새 터미널을 하나 열고 다음 명령을 실행합니다.
watch -n 1 nvidia-smi
1초마다 GPU 상태가 갱신됩니다.
TensorFlow 프로그램을 실행하면 다음 항목이 변하는 것을 볼 수 있습니다.
GPU Memory
GPU Utilization
Power
Python Process
GPU 메모리 사용량이 증가하면 TensorFlow가 GPU를 실제로 사용하고 있다는 것을 쉽게 확인할 수 있습니다.
종료하려면 다음을 누릅니다.
Ctrl + C

