C++에서 ONNX runtime을 사용 방법에 대한 설명을 듣고 정리해보았습니다.
ONNX runtime를 사용하는 이유?
- Open Neural Network Exchange (ONNX) → 프레임워크 상호운용성 및 하드웨어 최적화 접근성을 위한 라이브러리
- ML 모델의 공통 표준 포맷
- Tensorflow, Keras, Pytorch 모델 → onnx export 가능
- ML 모델의 제품화, 라이브러리화, API화
- ML 모델 암호화
(*onnx로 포맷 변환은 메모리 누수 등의 문제와는 관련없음, *.pt, *.pth등의 파일을 표준 포맷을 변환하는 것)
C++로 ONNX runtime 사용하기
- export된 onnx 모델 경로에 위치(encoder.onnx 등의 *.onnx 포맷의 변환된 형태)
- Onnx 세션을 만들어서 사용한다. 언어별 세션 생성방법은 공홈을 참고하면 된다.
- 다음 코드에서는 세션을 생성하고, 멀티프로세싱을 위한 스레드 풀을 만들고 있다.
Ort::Session* OnnxComponent::CreateOnnxSession(std::string strPathName)
{
Ort::SessionOptions session_options;
session_options.SetIntraOpNumThreads(1);
session_options.SetInterOpNumThreads(1);
session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);
return new Ort::Session(m_Environment, strPathName.c_str(), session_options);
}
- Tensorflow의 thread 세팅하는 함수와 같은 역할을 한다. ({inter, intra}_op_parallelism_threads)
Thread pool이 무엇인가?
Process와 Thread의 차이는?
Process가 만들어지면 process 내부에 thread가 만들어진다.
Multi-thread를 만든다는 것은 프로세스 안에 쓰레드1,2,3,..를 만드는 것을 의미한다.
Thread Pool을 사용한다는 것
각 쓰레드는 큐를 계속 보고 있음, 각 쓰레드가 먼저 끝나면 잡을 또 가져가서 처리한다. 예를 들어 쓰레드를 두 개 만든다. 큐를 만들어놓고, 큐에다가 job1, job2,…를 넣고, 각 쓰레드는 큐를 계속 보고 있다, 각 쓰레드가 먼저 끝나면 잡을 또 가져가서 처리한다.
Inference 과정에서는..?
- 접속할때마다 스레드를 만든다고 가정하자. 두명의 접속자가 인퍼를 한다면, 스레드 풀은 한개고, 프로세스 한 개에 스레드 여러개를 만들어도 큐는 하나이기 때문에, 큐 길이만 늘어나서 속도가 늘어난다.
- 이는 여러개의 프로세스를 만드는 걸로 모델 서빙을 해결할 수 있으나, 이 경우, 요청을 매번 어느 프로세스로 보내는가는 서버에서 잘 관리할 것.
- 파이썬으로 멀티프로세싱하는 경우, Ray를 사용하자
참고해볼만한 Onnx runtime C++ 예제
https://github.com/leimao/ONNX-Runtime-Inference
'Dev Notes > ML' 카테고리의 다른 글
[debug] tokenizer special token 추가 시 임베딩 사이즈 조절 하기 (0) | 2024.07.30 |
---|---|
Deepspeed 배치 사이즈 관련 파라미터 정리 (0) | 2023.08.20 |
머신러닝 프로덕션 코드를 구성하는 방법 (0) | 2023.06.25 |
Torchserve 사용 방법과 경로 설정 (0) | 2023.04.20 |
[MLops 기초] 프로덕션 환경에서의 머신러닝 시스템이란? (0) | 2023.04.18 |