이번 주 CloudNeta 스터디 주제는 Monitoring 이라 요즘 생각하고 있는 KServe의 모니터링과 관련된 글을 써보려고 한다.
KServe는 ML Serving tool이니까, ML 시스템의 모니터링에 대한 얘기가 되어야 할 것 같다.
ML system 에서의 Monitoring
ML 시스템에서의 모니터링은 다른 모니터링과 뭐가 다를까에 대해서 참고할 만한 책이 있다.
최근에 읽고 있는 Reliable Machine Learning 이란 책인데,
이 책의 9장은 Monitoring and Observability이다.
거기서 이론적인 부분을 좀 참고해볼 수 있을 것 같아서 일부만 갖고 와봤다.
- Monitoring과 Observability란 뭘까?
- Monitoring은 시스템의 성능에 대한 데이터를 제공하며, 이러한 데이터는 합리적인 방식으로 저장, 액세스 및 표시할 수 있도록 만들어진다.
- Observability는 소프트웨어의 속성으로, 올바르게 작성된 모니터링 데이터를 사용하여 시스템의 동작을 올바르게 추론할 수 있음을 의미한다.
그리고 그런 모니터링 활동을 전체 모델 수명 주기 전반에 걸쳐서 적용해야 한다고 적고 있다.
특히 머신러닝은 개발 환경과 프로덕션 환경이 몹시 다를 수 있으므로 고려사항이 많은 것 같다.
- 비즈니스 목표와의 연계
다른 모니터링 시스템들도 특히 그렇겠지만 비즈니스 목표를 염두에 두고, 배포된 모델에서 뿜어내는 메트릭과 KPI를 연계하는 것이 특히 중요하다고 한다.
비즈니스 인사이트는 없는데 인프라 인사이트만 많은 모니터링은 특히 무용지물에 가깝다고 적고 있으며,
특히 머신러닝이므로, 개발부터 프로덕션까지 모델 지표와 상호 연관지어가며 전체 과정을 추적해야 한다고 한다.
- 수집 대상
- input data.. 세트 크기와 분포 , raw와 feature의 비교, 데이터의 최신성
- 데이터에 대한 액세스 속도, feature store로 이동이 정상적으로 이루어지고 있는가
- processing은 충분히 빠르고 성공적인지,
- 모델 생성시 CPU, Memory, I/O
- 모델 생성에 걸리는 시간과 크기, 테스트 프로세스는 있고 통과 하는지
- 모델에 대한 쿼리는 얼마나 걸리나
- …
KServe에서 뭘 모니터링 해볼까
저런 요구사항들을 충족하기위해서 KServe에서도 뭔가 해볼 수 있는 것들이 있다.
인프라 레벨에서 이미 많이 분석하는 메트릭들이나 커스텀으로 개발 해야 하는 것 말고 이미 메트릭을 뿜을 준비가 되어있는 것 중에 KServe에서 좀 다르게 수집해볼 수 있는 것들이 있다.
그 중에서 Kserve는 Knative 을 활용하니 여기서 나오는 메트릭도 수집해볼 수 있을 것 같다.
그리고 물론 운영 중인 모델의 종류에 따라 수집하는 메트릭이라는건 많이 달라질 것 같아서 예시를 하나 들어야 한다.
요새 매우 많이 유명한 ChatGPT 같은 대화형 언어모델이나 Stable-diffusion 같은 경우
텍스트로 들어오는 prompt를 수집해서 가공하는 경우가 있을 것 같다.
이런 경우에는 Loki를 써볼 수 있다.
Knative (Prometheus)
KServe에서는 Istio + Knative를 중간 레이어로 사용한다는 사실과 그 역할을 이전 글에서 쓴 적이 있었다.
KServe InferenceService의 autoscailing 기능에 대해서 생각해보면, 아래 문서를 볼 수 있다.
https://knative.dev/docs/serving/autoscaling/
Knative Pod Autoscaler(KPA)를 이용해서 InferenceService의 autoscailing 기능을 제공한다는 사실을 알 수 있다.
그럼 그 KPA 는 어떤 metric 으로 기준을 삼아서 auto scailing을 하는지는 아래 문서를 보면 된다.
https://knative.dev/docs/serving/autoscaling/autoscaling-metrics/
아래 깃허브를 보면 autoscailer metric의 collector 코드를 볼 수 있다.
https://github.com/knative/serving/blob/main/pkg/autoscaler/metrics/collector.go
실제로 inferenceservice 배포 후 autoscaler의 configmap을 보면
# The requests per second (RPS) target default is what the Autoscaler will
# try to maintain when RPS is used as the scaling metric for a Revision and
# the Revision specifies unlimited RPS. Even when specifying unlimited RPS,
# the autoscaler will horizontally scale the application based on this
# target RPS.
# Must be greater than 1.0.
# NOTE: Only one metric can be used for autoscaling a Revision.
requests-per-second-target-default: "200"
이런 항목들이 있다.
어떤 식으로 기준을 잡아서 autoscailing을 동작시키는지 알 수 있다.
이 metric은 이미 뿜어낼 준비를 하고 있으므로 Prometheus를 통해 수집해올 수 있다.
수집은 아래 문서를 참고하자.
간단하게 kube-prometheus-stack으로 설치하고 메트릭을 수집해오는 법을 안내하고 있다.
https://knative.dev/docs/serving/observability/metrics/collecting-metrics/#about-prometheus
안내처럼 진행하면 이제 아래와 같이 Grafana dashboard 에서 Prometheus datasource를 통해
knative metric을 조회해볼 수 있다.
아래와 같이 시각화도 시켜볼 수 있을 것이다.
같은 모델에 부하가 많이 들어와서 InferenceService를 scaleout하여 replicas를 5로 전개한다고 했을 때,
각 pod에 들어오는 호출량 이나 뭐 그런걸 볼 수 있을 것이다.
Loki
Loki는 Grafana Labs에서 개발한 오픈소스 로깅 플랫폼이다. 분산 환경에서 대규모 로그 데이터를 수집하고, 저장하며, 쿼리할 수 있는 기능을 제공한다.
Promtheus와 다른 점은 Loki는 pull이 아니고 push 방식을 사용한다는 점이다.
그러니까, 로그 데이터를 적극적으로 수집하지 않고, 대신 로그 스트림을 읽어들여서 로그 데이터를 수집한다.
Prometheus처럼 Kubernetes 상에서 유연하게 사용할 수 있는데, 로그 데이터를 효율적으로 저장할 수 있다.
기본적으로 compression과 distributed indexing을 사용해서 로그 데이터 저장 공간과 처리 속도를 최적화할 수 있다.
그리고 역시 Grafana dashboard에서 쉽게 시각화해서 볼 수 있다는 점이 장점이다.
위와 같은 데이터를 갖고 오기 위해서 Promtail은 이라는 에이전트를 사용한다.
쿠버네티스 기준으로 Promtail은 Daemonset의 형태로 각 노드에 배포된다. 그리고 해당 노드에 상주하면서
로그들을 긁고 로그 스트림에 레이블을 붙이고 Loki로 PUSH 하는 것이다.
출처 : https://grafana.com/blog/2019/01/02/closer-look-at-grafanas-user-interface-for-loki/
위의 예시 화면을 보면 Grafana dashboard에서 explore에서 datasource를 Loki로 지정한 모습을 볼 수 있다.
LogQL 이란 걸 사용해서 쿼리를 할 수 있다. 화면에서 보이는건 그냥 job이 prometheus인걸 긁은 것 같다.
시간대별로 수집된 로그를 시각화해서 보여주고
그 아래에는 실제 해당 로그들을 볼 수 있는데,
그걸 확장해보면 아래와 같은 방식으로 레이블들을 붙여놓은 모습을 볼 수 있다.
그래서 우리의 KServe로 배포 중인 모델로 돌아오면...
이를 이용해서 LogQL로 쿼리를 해서 데이터를 이리저리 발라내서 볼 수 있다.
아래처럼 미리 Pod마다 떨구도록 해둔 prompt들을 어떤 것들이 있나 직접 볼 수 있도록 긁어온다던가
혹은 아래처럼 그 log들을 metric 삼아 요청이 들어오는 것에 대한 그래프도 그려볼 수 있다.
LogQL쓰는 법은 이 문서를 보면 된다.
https://grafana.com/docs/loki/latest/logql/
마무리
그렇지만 사실 아직 이런 모델들의 모니터링들을 비즈니스와 어떻게 연계시킬지는 고민을 많이 해봐야 할 것 같다.
Reference
- https://www.oreilly.com/library/view/reliable-machine-learning/9781098106218/
- https://mokpolar.tistory.com/27
- https://knative.dev/docs/serving/autoscaling/
- https://knative.dev/docs/serving/autoscaling/autoscaling-metrics/
- https://github.com/knative/serving/blob/main/pkg/autoscaler/metrics/collector.go
- https://knative.dev/docs/serving/observability/metrics/collecting-metrics/#about-prometheus
- https://grafana.com/blog/2020/07/21/loki-tutorial-how-to-send-logs-from-eks-with-promtail-to-get-full-visibility-in-grafana/
- https://grafana.com/blog/2020/07/21/loki-tutorial-how-to-send-logs-from-eks-with-promtail-to-get-full-visibility-in-grafana/
- https://grafana.com/docs/loki/latest/logql/
'MLOps' 카테고리의 다른 글
KServe로 하는 Model Serving 이해하기 (6) | 2022.10.08 |
---|---|
이미지 예측 모델을 쿠버네티스에 배포하기 A to Z (Kubernetes Kubeflow KFServing InferenceService Custom Image) (0) | 2022.01.05 |