Incident Library
적용된 필터 기여 요인장애 중첩조직Hugging Face모두 풀기검색어 없이 필터만 적용한 목록입니다. 최근 사례부터입니다.
추천 필터 검색하면 검색어에서 찾은 분류 값이 여기에 나옵니다.

그래프

  • 원인
  • 구성 요소
  • 증상
  • 기여 요인
  • 사례

사례2건

2건 중 1~2번째

  1. 증상

    Hugging Face 팀은 SmolLM3 본 학습을 시작했다. 48개 노드의 H100 GPU 384개로 11T 토큰을 학습하는 일정이었다. 시작하고 몇 시간 안에 처리량이 가파르게 떨어졌고, 이런 급락이 여러 번 되풀이됐다. 처리량은 학습 중 초당 처리하는 토큰 수다. 처리량이 50% 떨어지면 한 달짜리 학습이 두 달짜리가 된다.

    촉발

    팀은 약 24 TB 전체 데이터셋을 여러 팀이 함께 쓰는 Weka 스토리지에 두고, 11T 토큰에 맞춘 실제 스텝 수로 본 학습을 시작했다.

    원인
    구성 요소
    기여 요인
    감지

    팀은 학습 중 초당 토큰 처리량을 기록하고 있었다. 학습을 시작하고 몇 시간 안에 이 값이 급락하는 것이 보였다. SmolLM3 에서 기대한 처리량은 초당 13,500에서 14,000 토큰이었다. 팀은 처리량이 이 범위를 계속 벗어나면 위험 신호로 보았다. 그리고 노드 모니터링 지표에서 처리량이 떨어진 시점과 디스크 읽기 지연이 급증한 시점이 겹치는 것을 보고 스토리지를 원인으로 짚었다.

    조치
    • 데이터셋을 Weka 에서 빼서 각 노드의 로컬 NVMe RAID 스크래치 스토리지에 올렸다.
    • 교체한 노드에 데이터를 채울 때 S3 에서 s5cmd 로 24 TB 를 받으면 3시간이 걸렸다. 그래서 같은 데이터센터의 정상 노드에서 fpsync 로 복사해 1.5시간으로 줄였다.
    • 데이터셋을 미리 올려 둔 예비 노드 하나를 Slurm 예약에 넣어 두고, 노드가 죽으면 바로 예비 노드로 바꿨다.
    • 노드 하나에서도 급락을 재현해 하드웨어를 원인에서 뺐고, 약 3M 스텝과 32k 스텝으로 각각 돌려 원인을 스텝 수로 좁혔다.
    • Nanotron 의 nanosets 데이터로더를 SmolLM2 에서 쓰던 TokenizedBytes 데이터로더로 바꿔 넣자 급락이 사라졌다.
    • TokenizedBytes 로 바꾼 뒤 손실이 거칠어진 문제를 고치려고, 토큰화된 시퀀스를 에포크마다 다른 시드로 오프라인에서 미리 섞었다. 이 작업에 약 1시간이 걸렸다.
    교훈

    마감이 급할 때는 자기 구현을 디버깅하는 것보다 검증된 해법이나 빠른 우회책을 가져오는 편이 빠를 수 있다. 팀은 nanosets 의 인덱스 구현을 고치는 대신 TokenizedBytes 데이터로더를 가져왔다. 손실 문제도 데이터로더에 손대지 않고 오프라인에서 시퀀스를 미리 섞어 풀었다. 다만 임시방편을 너무 많이 쓰면 유지보수와 최적화가 어려운 누더기 시스템이 된다. 팀은 어블레이션과 본 학습 사이에 무엇이 바뀌었는지 정확히 알고 있었기 때문에 데이터셋 크기, 스텝 수, 하드웨어 상태를 하나씩 지워 가며 원인을 좁힐 수 있었다. 두 번째 문제는 처리량이 안정됐던 SmolLM2 의 데이터로더를 대규모로 검증하지 않은 데이터로더로 바꾸면서 생겼다.

  2. 증상

    2024-04-22 CET 8:45 부터 Hugging Face Hub 가 불안정해졌고, 9:30 에는 응답하지 않았다. 대부분의 사용자에게 Hub 웹사이트가 느려지거나 아예 열리지 않았다.

    촉발

    *_info_cache 컬렉션을 쓰는 무거운 API 요청이 갑자기 늘었다. 첫 장애 직전에는 https://huggingface.co/api/datasets/lighteval/mmlu/revision/main 호출이 크게 늘었고, 4월 23일 밤에는 https://huggingface.co/api/models/sentence-transformers/all-mpnet-base-v2/revision/main 요청이 늘었다.

    원인
    구성 요소
    기여 요인
    감지

    장애는 4월 22일 8:45 부터 Hub 가 불안정해지다가 9:30 에 응답하지 않으면서 드러났다. MongoDB Atlas 지표에서 읽기 전용 노드 두 대가 계속 재시작하는 것이 보였다. 24일 10:03 에는 팀이 수상한 지표를 보고 Hub 가 다시 멈추기 전에 rate limit 을 걸었다. 근본 원인은 URL 별 요청 수 그래프를 새로 만든 뒤에 찾았다.

    조치
    • Java/* user-agent 를 단 요청을 모두 막는 방화벽 규칙을 넣었다.
    • Hub 의 quicksearch 기능을 껐다.
    • MongoDB Atlas 클러스터를 손으로 tier 2 에서 tier 3 으로 올렸다.
    • AWS WAF 로 유지보수 모드를 켜 503 페이지를 띄우고 들어오는 트래픽을 막았다.
    • Hub 파드를 모두 0 으로 줄였다가 다시 올렸다.
    • 아주 엄격한 rate limit 을 걸었다.
    • 요청에 타임아웃을 넣고, 오래 걸리거나 응답 본문이 큰 데이터베이스 쿼리를 다시 짰다.
    후속 조치
    • 요청마다 평소 완료 시간에 맞춘 타임아웃을 넣었다.
    • 장애 중 오래 걸리거나 응답 본문이 큰 요청을 찾아 최적화하고, 잘못 설계된 데이터베이스 쿼리를 다시 짰다.
    • 쓰지 않는 오래된 인덱스를 지워 데이터베이스를 정리했다.
    • 장애 중 새 대시보드와 모니터링 지표를 만들었다.
    • *_info_cache 를 Redis 로 옮긴다.
    • 클라이언트가 요청을 취소하면 데이터베이스 요청도 취소할 수 있게 한다.
    교훈

    Hub 팀은 모든 차트를 봐도 답이 없을 때 URL 별 요청 수라는 새 그래프를 만들어서야 원인을 찾았다. 클라이언트가 떠난 뒤에도 서버가 데이터베이스 요청을 계속 돌리면, 서비스가 느려졌을 때 사용자가 누르는 새로고침이 부하를 몇 배로 키운다. 무거운 요청 몇 가지가 데이터베이스 전체를 흔들 수 있으므로 요청별 타임아웃과 취소가 필요하다. 팀은 이번 일로 어떤 지표를 더 가까이 봐야 장애를 미리 막을 수 있는지 알게 됐다. 원인을 찾는 데 2-3일이 걸렸고, 관계없는 장애가 동시에 겹쳐 복구가 더 힘들었다.

내 클러스터에도 있는지 확인하기

이 2건에서 가장 많이 나오는 구성 요소: 클러스터 오토스케일러, 애플리케이션 데이터베이스. kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이런 틈을 점검합니다. 점검 항목의 근거는 이 라이브러리와 같은 공개 보고서입니다.

원인별2