LibTorch 에서 pth 파일에 메타데이터 포함하는 방법이 있나요?

안녕하세요.
LibTorch 를 이용해 비쥬얼 스튜디오 2019에서
Mfc의 cpp 환경에서 파이썬에서 훈련한 pth 파일을 이용해
추론을 하려고합니다.

환경 설정 및 간단한 랜덤 텐서 출력은 마친 상태입니다.

여기서 문제는 추론할 모댈에대해 입력 이미지의 사이즈나
출력할 클래스의 개수 및 이름 등의 메타데이터를 c++에서는
어떻게 더룰지 입니다.
파이썬의 경우 딕트형태로 저장하고 불러오는게 쉽지만
C++은 어떻게 쓰시고 계신지요.
Onnx의경우에도 메타데이터가 읽고 쓸 수 있었지만
메모리 문제로(1.12.1) 다른 방법을 알아보고 있는 중입니다.

읽어주셔서 감사합니다

  • 아래 답변은 Anthropic의 Claude-2 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요 KimjaeHyun님,

pth 파일에 메타데이터를 포함하는 문제로 고민하고 계시다니 이해할 수 있습니다.

pth 파일은 주로 모델의 weight와 bias등의 파라미터 값들을 저장하는 데 사용되기 때문에 별도의 메타데이터를 저장하는 기능은 제공하고 있지 않습니다.

다만 몇 가지 대안적인 방법이 있습니다.

  1. pth 파일과 별도로 json이나 yaml 등의 형태로 메타데이터를 저장한 뒤, 이를 불러와 사용하는 방법이 있습니다.

  2. 모델 구조를 정의한 Python 코드 자체를 함께 배포하고, 이를 통해 메타데이터를 얻을 수 있습니다.

  3. onnx 포맷도 고려해보시기 바랍니다. onnx는 모델 파라미터와 구조까지 저장하며, 메타데이터도 함께 포함됩니다.

제가 아는 범위 내에서 위와 같이 몇 가지 제안을 드릴 수 있겠습니다. 보다 자세한 해결책이 필요하신 경우 추가로 질문 주시기 바랍니다.

감사합니다.


  • 답변이 어떠셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!
  • 아래 답변은 OpenAI의 GPT-4-Turbo 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요, 김재현님.

문의하신 내용을 정리해보면, LibTorch를 사용하여 C++ 환경에서 Python에서 훈련된 .pth 파일을 불러와 추론을 진행하고자 하시며, 특히 모델에 필요한 메타데이터(예: 입력 이미지의 사이즈, 클래스 개수 및 이름 등)를 C++에서 어떻게 다루는지에 대한 질문이신 것 같습니다.

PyTorch에서는 모델의 state_dict와 함께 메타데이터를 저장하고 불러오는 것이 가능합니다. Python에서는 이를 위해 torch.save 함수를 사용하여 딕셔너리 형태로 저장할 수 있으며, C++에서는 LibTorch의 직렬화 기능을 사용하여 이를 불러올 수 있습니다.

다음은 Python에서 모델과 메타데이터를 저장하는 예시 코드입니다:

import torch

# 가정: model은 훈련된 모델, metadata는 메타데이터를 담은 딕셔너리
metadata = {'input_size': (224, 224), 'num_classes': 10, 'class_names': ['class1', 'class2', ...]}
torch.save({
    'model_state_dict': model.state_dict(),
    'metadata': metadata
}, 'model_with_metadata.pth')

C++에서는 저장된 .pth 파일을 불러와서 메타데이터를 사용하는 방법은 다음과 같습니다:

#include <torch/script.h> // LibTorch header
#include <iostream>
#include <memory>

int main() {
    // 모델 파일 로드
    torch::jit::script::Module module;
    try {
        module = torch::jit::load("model_with_metadata.pth");
    }
    catch (const c10::Error& e) {
        std::cerr << "모델을 불러오는데 실패했습니다.\n";
        return -1;
    }

    // 메타데이터 추출
    auto metadata = module.attr("metadata").toGenericDict();
    auto input_size = metadata.at("input_size").toIntVector();
    auto num_classes = metadata.at("num_classes").toInt();
    auto class_names = metadata.at("class_names").toStrVector();

    // 메타데이터 사용
    std::cout << "Input Size: " << input_size[0] << "x" << input_size[1] << std::endl;
    std::cout << "Number of Classes: " << num_classes << std::endl;
    std::cout << "Class Names: ";
    for (const auto& name : class_names) {
        std::cout << name << " ";
    }
    std::cout << std::endl;

    // 추론을 위한 모델 준비 및 사용
    // ...

    return 0;
}

위의 C++ 코드는 LibTorch를 사용하여 저장된 모델과 메타데이터를 불러오고, 메타데이터를 추출하여 사용하는 방법을 보여줍니다. module.attr("metadata")를 통해 Python에서 저장한 메타데이터에 접근할 수 있습니다.

더 자세한 정보는 PyTorch 공식 문서의 직렬화 및 모델 저장/불러오기 섹션을 참조하시면 도움이 될 것입니다:

질문에 대한 답변이 충분하지 않거나 추가적인 정보가 필요하시면 언제든지 더 질문해 주세요. 제 답변이 정확하지 않을 수도 있으니, 실제 적용하실 때는 관련 문서를 참고하시는 것이 좋습니다.


  • 답변이 어떠셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!

이처럼 만든 부분을 c++에서 메타데이터를 불러오는 방법은 잘 봤습니다.
model_state_dict': model.state_dict(), 은 어떻게 불러오나요?

  • 아래 답변은 OpenAI의 GPT-4 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요, KimjaeHyun님.

문제 상황에 대해 정리해보겠습니다. LibTorch를 사용하여 Visual Studio 2019에서 MFC 기반의 C++ 환경에서 Python에서 훈련한 .pth 파일을 이용한 추론을 진행하고 계시며, 기본적인 환경 설정과 텐서 출력까지는 성공적으로 마치셨습니다. 그러나 C++ 환경에서 모델에 필요한 메타데이터(예: 입력 이미지의 사이즈, 출력 클래스의 개수 및 이름 등)를 어떻게 포함하고 불러올 수 있는지에 대한 질문을 주셨습니다.

C++에서 메타데이터를 다루는 방법은 여러 가지가 있을 수 있으나, 일반적으로는 파일 시스템을 이용하거나, 모델 파일 자체에 메타데이터를 포함시키는 방법을 사용할 수 있습니다. PyTorch의 torch::jit::script::Module을 사용하여 모델을 불러올 때, 추가적인 정보를 JSON 파일이나 별도의 설정 파일로 관리하거나, 모델 파일 내에 직접 저장하는 방법을 고려할 수 있습니다.

다음은 C++에서 JSON 파일을 이용하여 메타데이터를 불러오는 예시 코드입니다. 이를 위해 nlohmann/json 라이브러리를 사용할 수 있습니다.

#include <torch/script.h> // torch::jit::script::Module
#include <iostream>
#include <memory>
#include <fstream>
#include "json.hpp" // nlohmann/json

int main() {
    // 모델을 불러옵니다.
    torch::jit::script::Module module;
    try {
        module = torch::jit::load("model.pth");
    }
    catch (const c10::Error& e) {
        std::cerr << "모델을 불러오는데 실패했습니다.\n";
        return -1;
    }

    // 메타데이터를 불러옵니다.
    std::ifstream i("metadata.json");
    nlohmann::json metadata;
    i >> metadata;

    // 메타데이터 사용 예시
    int input_size = metadata["input_size"];
    int num_classes = metadata["num_classes"];
    std::vector<std::string> class_names = metadata["class_names"];

    // 추론을 수행합니다.
    // ...

    return 0;
}

위 코드에서 metadata.json 파일은 다음과 같은 형식을 가질 수 있습니다.

{
    "input_size": 224,
    "num_classes": 10,
    "class_names": ["class1", "class2", "class3", ...]
}

nlohmann/json 라이브러리는 JSON 데이터를 쉽게 다룰 수 있게 해주는 C++ 라이브러리입니다. 이 라이브러리를 사용하려면 프로젝트에 포함시켜야 합니다. 라이브러리에 대한 자세한 정보는 다음 링크에서 확인하실 수 있습니다: GitHub - nlohmann/json: JSON for Modern C++

LibTorch와 관련된 더 자세한 정보는 PyTorch 공식 문서에서 확인하실 수 있습니다. C++에서의 모델 로딩 및 사용에 대한 자세한 내용은 다음 링크를 참조하세요: https://pytorch.org/cppdocs/loading.html

이 답변이 KimjaeHyun님의 문제 해결에 도움이 되길 바랍니다. 추가적인 질문이나 궁금한 점이 있으시면 언제든지 질문해 주세요.


  • 답변이 어떠셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!

추론을 위해 모댈을 준비하는 부분도 궁금합니다.

  • 아래 답변은 Anthropic의 Claude-2 모델로 자동 생성한 것으로, 정확하지 않을 수 있습니다.
  • 잘못된 답변을 보셨다면 댓글로 첨삭 지도 부탁드립니다. :sweat_smile:

안녕하세요 KimjaeHyun 님,

LibTorch에서 pth 파일에 메타데이터를 포함하는 문제에 대해 질문해 주셔서 대단히 감사합니다.

제가 문제를 정확히 이해했다면, KimjaeHyun님은 Python에서 학습한 모델을 LibTorch와 C++을 사용하여 추론하려고 하시는데, 문제는 pth 파일에 입력 이미지 크기, 출력 클래스 수 및 이름과 같은 메타데이터를 어떻게 처리할 지 모르겠다는 것이 맞습니까?

Python에서는 딕셔너리와 같은 데이터 구조에 이 메타데이터를 저장하고 로드하기 쉽지만, C++에서는 어떻게 해야 할지 잘 모르겠다고 하셨습니다.

이 문제를 해결하기 위한 한 가지 방법은 pth 파일과 별도로 json 파일을 만들어 메타데이터를 저장하는 것입니다. 예를 들어 다음과 같은 json 파일을 만들 수 있습니다:

{
  "input_size": [224, 224],
  "num_classes": 1000, 
  "classes": ["class1", "class2", ... "class1000"]   
}

그리고 C++코드에서 이 json 파일을 파싱하여 메타데이터에 접근할 수 있습니다.

다른 한 가지 방법은 클래스의 serializing/deserializing 매커니즘을 사용하는 것입니다. 즉, 메타데이터를 포함하는 사용자 정의 C++ 클래스를 만들고 여기에 필요한 정보를 저장합니다. 그런 다음 이 클래스의 인스턴스를 serializing하여 pth 파일에 저장할 수 있습니다. deserializing 시에 이 데이터에 다시 접근할 수 있습니다.

아래는 간단한 사용자 정의 Serialization 클래스의 예시 코드입니다:

class ModelMetadata {
public:
  int input_size[2];
  int num_classes;
  vector<string> classes;
  
  // serializing/deserializing 함수
  
  template <class Archive>
  void serialize(Archive & ar, const unsigned int version)
  {
    ar & input_size;
    ar & num_classes;    
    ar & classes;
  }

};

이 중 어느 것이든 KimjaeHyun님의 상황에 맞는 좋은 해결책이 될 수 있다고 생각합니다.

추가로 문의 사항이나 도움이 더 필요한 부분이 있으시면 언제든지 댓글 남겨주세요. 최대한 빠르게 답변 드리겠습니다.


  • 답변이 어떠셨나요? 괜찮았다고 생각하신다면 아래 :heart:를 한 번 눌러주시길 부탁드려요!

안녕하세요
저도 오래전에 C++ 인퍼런스를 해봐서 기억이 가물가물한데요.
C++ 에서는 Pytorch jit, script 파일을 로드해서 interpreter의 forward 만 실행 가능했던걸로 기억납니다. 그래서 메타데이터가 포함되어 있어도 읽을 수가 없었던 것으로 기억합니다. 그래서 추가 정보를 별도의 파일로 같이 가지고 다녔습니다.

하지만 동일한 파일을 파이썬에서 로드를 한다면 메타데이터를 일어 오실수 있습니다. 변수가 바로 접근이 가능하기 때문이죠.

모델을 준비하는 부분은 어떤게 궁금하실까요?