Ubuntu 실습(5)

zeusqoi·2026년 9월 7일

개인공부

목록 보기
12/42

지난 글에서는 TensorFlow Serving을 이용해 MNIST 모델을 Docker 환경에서 배포하고, REST API를 통해 단일 이미지 및 여러 이미지를 Batch 형태로 예측해 보았다.

이번에는 TensorFlow Serving에서 제공하는 모델 버전 관리(Model Versioning) 기능을 실습해 보았다.

기존에 학습한 모델을 v1으로 유지하면서 새로운 모델을 v2로 추가하고, 두 버전을 동시에 서비스한 뒤 각각의 모델을 지정하여 예측하는 과정까지 진행해 보았다.


1. 기존 모델 확인

먼저 현재 TensorFlow Serving에서 서비스 중인 MNIST 모델의 상태를 확인했다.

curl http://127.0.0.1:8501/v1/models/mnist

처음에는 다음과 같이 v1 모델만 서비스되고 있었다.

{
  "model_version_status": [
    {
      "version": "1",
      "state": "AVAILABLE",
      "status": {
        "error_code": "OK",
        "error_message": ""
      }
    }
  ]
}

현재 모델의 버전은 1이고, AVAILABLE 상태이므로 정상적으로 서비스되고 있는 것을 확인할 수 있다.


2. SavedModel의 버전 구조 확인

현재 프로젝트의 saved_model 디렉터리를 확인했다.

ls -R saved_model

결과는 다음과 같았다.

saved_model/
└── 1/
    ├── assets
    ├── fingerprint.pb
    ├── saved_model.pb
    └── variables/
        ├── variables.data-00000-of-00001
        └── variables.index

TensorFlow Serving에서는 모델 디렉터리 내부의 숫자로 모델 버전을 구분할 수 있다.


3. 새로운 v2 모델 생성

기존 mnist.py를 복사하여 v2 모델을 만들었다.

cp mnist.py mnist_v2.py

기존 모델은 5 epoch으로 학습했기 때문에 v2에서는 10 epoch으로 변경했다.

model.fit(
    x_train,
    y_train,
    epochs=10
)

그리고 모델 저장 경로도 v2로 변경했다.

기존:

model.export("saved_model/1")

변경:

model.export("saved_model/2")

수정한 파일을 실행했다.

python mnist_v2.py

학습이 완료되면 saved_model/2가 생성된다.

최종적으로 다음과 같은 구조가 만들어졌다.

saved_model/
├── 1/
│   ├── assets/
│   ├── fingerprint.pb
│   ├── saved_model.pb
│   └── variables/
│
└── 2/
    ├── assets/
    ├── fingerprint.pb
    ├── saved_model.pb
    └── variables/

기존 v1 모델은 그대로 유지하면서 새로운 v2 모델을 추가할 수 있었다.


4. TensorFlow Serving에서 v2 확인

새로운 v2 모델이 생성된 후 TensorFlow Serving의 모델 상태를 다시 확인했다.

curl http://127.0.0.1:8501/v1/models/mnist

새로운 v2가 로드된 것을 확인할 수 있었다.

이후 기본 예측 API를 호출했다.

curl -X POST \
  http://127.0.0.1:8501/v1/models/mnist:predict \
  -H "Content-Type: application/json" \
  -d @request.json

정상적으로 예측 결과가 반환되었다.

예측 결과는 0~9에 해당하는 10개의 값으로 반환되며, 가장 큰 값을 가진 인덱스를 예측 클래스로 사용할 수 있다.


5. v2 모델 Batch 예측

이전에 사용했던 batch_mnist.py를 이용하여 v2 모델에 MNIST 테스트 데이터 1,000장을 한 번에 전달했다.

python batch_mnist.py

실행 결과:

===== MNIST Batch 예측 =====
Batch 크기: 1000
입력 shape: (1000, 28, 28)

===== 예측 결과 =====

정답: 978/1000
정확도: 97.8%
요청 시간: 87.65 ms

v2 모델도 1,000개의 테스트 데이터 중 978개를 정확하게 예측하여 97.8%의 정확도를 기록했다.

이전 v1 모델 역시 1,000장 테스트에서 97.8%의 정확도를 기록했기 때문에 이번 실습에서는 정확도 차이는 발생하지 않았다.


6. 특정 모델 버전으로 예측하기

TensorFlow Serving에서는 모델 이름뿐만 아니라 특정 버전을 지정하여 예측 요청을 보낼 수도 있다.

먼저 v1 모델을 지정하여 요청했다.

curl -X POST \
  http://127.0.0.1:8501/v1/models/mnist/versions/1:predict \
  -H "Content-Type: application/json" \
  -d @request.json

정상적으로 예측 결과가 반환되었다.

v2 모델도 동일한 방식으로 요청했다.

curl -X POST \
  http://127.0.0.1:8501/v1/models/mnist/versions/2:predict \
  -H "Content-Type: application/json" \
  -d @request.json

v2 역시 정상적으로 예측 결과가 반환되었다.

같은 request.json을 사용했지만 모델 버전에 따라 내부적인 예측 점수는 다르게 나타났다.

예를 들어 v1의 결과는:

[-16.8027515, -4.0355072, -4.23719168, 8.32548428,
 -25.7745361, 12.6973715, -17.9552364, -5.77497387,
 -12.6859808, -7.36994362]

v2에서는:

[-16.8850555, -8.47405148, -5.74707603, 6.11848974,
 -38.9685287, 16.3971634, -18.0521622, -11.4762402,
 -13.3883448, -9.20674133]

가 반환되었다.

두 모델 모두 가장 큰 값이 5번 클래스에 해당하므로 동일하게 5로 예측했다.


7. v1과 v2 동시에 서비스하기

처음에는 v2가 추가되면서 v1을 직접 지정한 요청에서 다음과 같은 오류가 발생했다.

{
  "error": "Servable not found for request: Specific(mnist, 1)"
}

이는 saved_model/1이 삭제된 것이 아니라, 현재 TensorFlow Serving에서 v1이 서비스 대상에서 제외된 상태였기 때문이다.

이를 해결하기 위해 모델 설정 파일을 생성했다.

nano models.config

다음 내용을 작성했다.

model_config_list {
  config {
    name: "mnist"
    base_path: "/models/mnist"
    model_platform: "tensorflow"
    model_version_policy {
      all {
      }
    }
  }
}

여기서 중요한 부분은 다음 설정이다.

model_version_policy {
  all {
  }
}

all 정책을 사용하면 모델 저장소에 존재하는 여러 버전을 서비스할 수 있다.

기존 TensorFlow Serving 컨테이너를 중지하고 삭제했다.

docker stop naughty_ellis
docker rm naughty_ellis

그 다음 models.config를 컨테이너에 연결하여 TensorFlow Serving을 다시 실행했다.

docker run -d \
  --name naughty_ellis \
  -p 8501:8501 \
  -v ~/tensorflow-study/saved_model:/models/mnist \
  -v ~/tensorflow-study/models.config:/models/models.config \
  tensorflow/serving \
  --model_config_file=/models/models.config

8. v1과 v2 동시 서비스 확인

컨테이너가 정상적으로 실행된 후 모델 상태를 확인했다.

curl http://127.0.0.1:8501/v1/models/mnist

결과:

{
  "model_version_status": [
    {
      "version": "2",
      "state": "AVAILABLE",
      "status": {
        "error_code": "OK",
        "error_message": ""
      }
    },
    {
      "version": "1",
      "state": "AVAILABLE",
      "status": {
        "error_code": "OK",
        "error_message": ""
      }
    }
  ]
}

이를 통해 v1과 v2 모델이 동시에 AVAILABLE 상태로 서비스되고 있는 것을 확인할 수 있었다.

최종적으로 다음과 같은 구조가 되었다.

                 TensorFlow Serving
                        │
                  MNIST Model
                        │
              ┌─────────┴─────────┐
              ↓                   ↓
           Version 1           Version 2
          AVAILABLE            AVAILABLE
              │                   │
              ↓                   ↓
        /versions/1:predict  /versions/2:predict

마무리

이번 실습에서는 TensorFlow Serving의 모델 버전 관리 기능을 직접 확인해 보았다.

기존에 학습한 모델을 saved_model/1에 유지한 상태에서 새로운 모델을 saved_model/2로 추가하고, TensorFlow Serving에서 새로운 버전을 로드하는 과정을 실습했다.

또한 모델 설정 파일을 이용하여 v1과 v2를 동시에 서비스하고, API 요청에서 특정 버전을 지정하여 각각의 모델을 호출해 보았다.

이번 실습을 통해 다음 내용을 확인할 수 있었다.

  • TensorFlow Serving에서 모델 버전을 디렉터리로 관리
  • saved_model/1, saved_model/2 형태로 새로운 모델 추가
  • 새로운 모델 버전 로드 및 상태 확인
  • 특정 모델 버전을 지정하여 예측
  • model_version_policy를 이용한 여러 버전 동시 서비스
  • 동일한 입력에 대해 v1과 v2의 예측 결과 비교

0개의 댓글