웹훅 가이드: 모델·데이터셋 자동 메타데이터 품질 검토 설정
웹훅 가이드: 모델·데이터셋 자동 메타데이터 품질 검토 설정 (Setup an automatic metadata quality review for models and datasets)
이 가이드는 Hub에서 사용자 또는 조직의 모델·데이터셋 변경에 반응하고, 변경된 저장소에 대한 '메타데이터 검토(metadata review)'를 만드는 시스템을 구축하는 방법을 안내해요.
출처: 문서
본문
이 가이드는 Hub에서 사용자 또는 조직의 모델·데이터셋 변경에 반응하고 변경된 저장소에 대한 'metadata review'를 생성하는 시스템을 만드는 과정을 안내합니다.
무엇을, 왜 만드는가? (What are we building and why?)
이 특정 워크플로의 기술적 세부 사항에 들어가기 전에, 무엇을 만들고 왜 만드는지 간단히 정리해 볼게요.
모델 카드와 데이터셋 카드는 머신러닝 모델과 데이터셋을 문서화하는 필수 도구입니다. Hugging Face Hub는 YAML 헤더 블록을 포함한 README.md 파일을 사용해 모델·데이터셋 카드를 생성해요. 이 YAML 섹션은 모델 또는 데이터셋과 관련된 메타데이터를 정의합니다. 예를 들어:
---
language:
- "List of ISO 639-1 code for your language"
- lang1
- lang2
tags:
- tag1
- tag2
license: "any valid license identifier"
datasets:
- dataset1
---
이 메타데이터는 잠재적 사용자를 위한 모델·데이터셋의 필수 정보를 담고 있습니다. 예를 들어 라이선스는 모델이나 데이터셋이 어떤 조건으로 사용될 수 있는지를 정의해요. Hub 사용자는 YAML 메타데이터에 정의된 필드를 필터로 사용해 특정 기준에 맞는 모델·데이터셋을 식별할 수도 있습니다.
이 블록에 정의된 메타데이터는 모델·데이터셋의 잠재적 사용자에게 필수적이므로, 이 섹션을 완성하는 것이 중요합니다. 팀이나 조직 환경에서 모델·데이터셋을 Hub에 푸시하는 사용자들은 이 YAML 메타데이터 블록의 중요성에 대한 이해도가 서로 다를 수 있어요. 팀의 누군가가 이 메타데이터를 검토하는 책임을 질 수도 있지만, 대신 이 문제를 돕는 자동화를 할 수도 있습니다. 결과는 Hub의 저장소가 변경될 때 자동으로 게시되거나 업데이트되는 메타데이터 검토 보고서입니다. 메타데이터 품질 측면에서 이 시스템은 CI/CD와 유사하게 동작해요.

예시 검토도 여기에서 찾을 수 있어요.
Hub 클라이언트 라이브러리를 사용해 모델 검토 카드 만들기 (Using the Hub Client Library to create a model review card)
huggingface_hub는 Hub와 상호작용할 수 있게 해주는 Python 라이브러리입니다. 이 라이브러리를 사용해 DatasetCard.load 또는 ModelCard.load 메서드로 Hub에서 모델·데이터셋 카드를 다운로드할 수 있어요. 특히, 이 메서드들로 모델·데이터셋 카드의 YAML에 정의된 메타데이터가 포함된 Python 딕셔너리를 불러올 거예요. 이 메서드들을 감싸고 예외 처리를 하는 작은 Python 함수를 만들겠습니다.
from huggingface_hub import DatasetCard, ModelCard
from huggingface_hub.utils import EntryNotFoundError
def load_repo_card_metadata(repo_type, repo_name):
if repo_type == "dataset":
try:
return DatasetCard.load(repo_name).data.to_dict()
except EntryNotFoundError:
return {}
if repo_type == "model":
try:
return ModelCard.load(repo_name).data.to_dict()
except EntryNotFoundError:
return {}
이 함수는 저장소와 관련된 메타데이터가 담긴 Python 딕셔너리를 반환합니다(메타데이터가 없으면 빈 딕셔너리).
{'license': 'afl-3.0'}
메타데이터 검토 보고서 만들기 (Creating our metadata review report)
저장소와 관련된 메타데이터가 담긴 Python 딕셔너리를 얻었으면, 메타데이터 검토를 위한 'report card'를 만들겠습니다. 이 경우, 값을 원하는 일부 메타데이터 필드를 정의해 메타데이터를 검토할 거예요. 예를 들어 license 필드가 항상 완성되어 있는지 확인하고 싶을 수 있어요. 메타데이터를 평가하려면 원하는 필드 중 어느 메타데이터 필드가 존재하는지 세고, 보고 싶은 필수 메타데이터 필드의 커버리지를 기준으로 백분율 점수를 반환합니다.
메타데이터가 담긴 Python 딕셔너리가 있으므로, 이 딕셔너리를 순회하며 원하는 키가 있는지 확인할 수 있어요. 원하는 메타데이터 필드(딕셔너리의 키)가 없으면 값을 None으로 할당합니다.
def create_metadata_key_dict(card_data, repo_type: str):
shared_keys = ["tags", "license"]
if repo_type == "model":
model_keys = ["library_name", "datasets", "metrics", "co2", "pipeline_tag"]
shared_keys.extend(model_keys)
keys = shared_keys
return {key: card_data.get(key) for key in keys}
if repo_type == "dataset":
# [...]
이 함수는 모델·데이터셋에 필요한 메타데이터 필드를 나타내는 키가 담긴 딕셔너리를 반환합니다. 딕셔너리 값은 해당 필드에 입력된 메타데이터를 포함하거나, 그 메타데이터 필드가 YAML에 없으면 None이 됩니다.
{'tags': None,
'license': 'afl-3.0',
'library_name': None,
'datasets': None,
'metrics': None,
'co2': None,
'pipeline_tag': None}
이 딕셔너리를 얻으면 메타데이터 보고서를 만들 수 있어요. 간결함을 위해 전체 코드는 여기에 포함하지 않지만, 이 Webhook용 Hugging Face Spaces 저장소에 전체 코드가 들어 있습니다.
메타데이터 커버리지 딕셔너리의 데이터를 더 보기 좋게 만든 markdown 테이블을 만드는 함수 하나를 만듭니다.
def create_metadata_breakdown_table(desired_metadata_dictionary):
# [...]
return tabulate(
table_data, tablefmt="github", headers=("Metadata Field", "Provided Value")
)
또한 원하는 메타데이터 필드 중 존재하는 비율을 나타내는 점수를 생성하는 Python 함수도 있습니다.
def calculate_grade(desired_metadata_dictionary):
# [...]
return round(score, 2)
그리고 메타데이터 검토를 위한 markdown 보고서를 만드는 Python 함수가 있습니다. 이 보고서는 점수와 메타데이터 테이블, 그리고 보고서에 무엇이 들어 있는지에 대한 설명을 담고 있어요.
def create_markdown_report(
desired_metadata_dictionary, repo_name, repo_type, score, update: bool = False
):
# [...]
return report
검토를 어떻게 자동으로 게시하나요? (How to post the review automatically?)
이제 markdown 형식의 메타데이터 검토 보고서가 있습니다. huggingface_hub 라이브러리를 사용해 이 검토를 게시할 거예요. Hub에서 받은 Webhook 데이터를 받아 파싱하고 메타데이터 보고서를 만드는 함수를 정의합니다. 보고서가 이전에 생성되었는지 여부에 따라, 함수는 새 보고서를 만들거나 기존 메타데이터 검토 스레드에 새 이슈를 게시합니다.
def create_or_update_report(data):
if parsed_post := parse_webhook_post(data):
repo_type, repo_name = parsed_post
else:
return Response("Unable to parse webhook data", status_code=400)
# [...]
return True
[!TIP]
:=는 Python 3.8에 추가된 대입 표현식 연산자(흔히 walrus operator로 불림)의 문법입니다. 이 문법에 대한 의견은 사람마다 다르며, 이것을 사용하지 않아도 Python이 코드를 평가하는 방식은 바뀌지 않습니다. 이 연산자에 대해 더 알아보려면 Real Python 문서를 읽어보세요.
Hub의 변경에 응답하는 Webhook 만들기 (Creating a Webhook to respond to changes on the Hub)
이제 모델·데이터셋에 대한 메타데이터 검토 보고서를 만드는 핵심 기능이 준비되었습니다. 다음 단계는 Webhooks를 사용해 변경에 자동으로 응답하는 것입니다.
사용자 프로필에서 Webhook 만들기 (Create a Webhook in your user profile)
먼저 https://huggingface.co/settings/webhooks 로 가서 Webhook을 만드세요.
- Webhook이 청취할 대상 저장소를 몇 개 입력합니다(내 저장소나 소속 조직의 저장소로 제한하는 것이 좋을 거예요).
- Webhook을 더 안전하게 만들 시크릿을 입력합니다(무엇을 고를지 모르겠다면 비밀번호 생성기로 충분히 긴 랜덤 문자열을 만들어 사용할 수 있어요).
- 지금은
Webhook URL파라미터에 더미 URL을 전달할 수 있습니다.
Webhook은 이렇게 생겼습니다:

새 Bot 사용자 프로필 만들기 (Create a new Bot user profile)
이 가이드는 메타데이터 검토를 게시할 별도의 사용자 계정을 만듭니다.

[!TIP] Hub에서 다른 사용자와 상호작용할 봇을 만들 때는 계정을 명확히 "Bot"으로 표시해 주시기 바랍니다(프로필 스크린샷 참고).
Webhook 리스너 만들기 (Create a Webhook listener)
이제 Webhook 이벤트를 청취할 방법이 필요합니다. Webhook 이벤트를 청취하는 데 사용할 수 있는 도구는 많아요. Zapier나 IFTTT 같은 많은 기존 서비스가 Webhooks를 사용해 액션을 트리거할 수 있습니다(예: 모델이 업데이트될 때마다 트윗 게시). 이 경우 FastAPI로 Webhook 리스너를 구현하겠습니다.
FastAPI는 Python 웹 프레임워크입니다. FastAPI를 사용해 Webhook 리스너를 만들 거예요. 특히, /webhook에서 POST 요청을 수락하는 라우트를 구현해야 합니다. 인증을 위해 X-Webhook-Secret 헤더를 우리 Docker 컨테이너에 런타임에 전달할 수 있는 WEBHOOK_SECRET 시크릿과 비교합니다.
from fastapi import FastAPI, Request, Response
import os
KEY = os.environ.get("WEBHOOK_SECRET")
app = FastAPI()
@app.post("/webhook")
async def webhook(request: Request):
if request.method == "POST":
if request.headers.get("X-Webhook-Secret") != KEY:
return Response("Invalid secret", status_code=401)
data = await request.json()
result = create_or_update_report(data)
return "Webhook received!" if result else result
위 함수는 Webhook 이벤트를 받아 변경된 저장소의 메타데이터 검토 보고서를 만들거나 업데이트합니다.
Space로 Webhook 앱 배포하기 (Use Spaces to deploy our Webhook app)
main.py 파일에 Webhook 앱에 필요한 모든 코드가 들어 있습니다. 배포하려면 Space를 사용합니다.
Space에서는 Docker로 앱을 실행할 거예요. Dockerfile이 앱 파일을 복사하고, 필요한 의존성을 설치하며, 애플리케이션을 실행합니다. KEY 변수를 채우기 위해 앞서 생성한 시크릿으로 Space에 WEBHOOK_SECRET 시크릿을 설정할 거예요. Docker Spaces에 대해 더 알아보려면 여기를 읽어보세요.
마지막으로 Webhook 설정의 URL을 내 Space의 URL로 업데이트해야 합니다. 컨텍스트 메뉴에서 Space의 "direct URL"을 얻을 수 있어요. "Embed this Space"를 클릭하고 "Direct URL"을 복사하세요.

이 URL을 얻으면 Webhook 설정의 Webhook URL 파라미터에 전달할 수 있습니다. 이제 모니터링하는 저장소가 변경될 때 봇이 검토를 게시하기 시작할 거예요!
결론과 다음 단계 (Conclusion and next steps)
이제 자동 메타데이터 검토 봇이 준비되었습니다! 이 가이드를 바탕으로 구축할 수 있는 아이디어 몇 가지:
- 우리 봇이 수행한 메타데이터 검토는 비교적 조잡했습니다; 메타데이터를 검토하는 더 복잡한 규칙을 추가할 수 있어요.
- 검토에 전체
README.md파일을 사용할 수 있습니다. - 내 조직에 특히 중요한 '규칙'을 정의하고 웹훅으로 이 규칙이 지켜지는지 확인하고 싶을 수 있어요.
Webhooks를 사용해 메타데이터 품질 앱을 만든다면 @davanstrien 을 태그해 주세요! 그걸 알게 되면 정말 좋겠습니다!
더 알아보기 (Learn more)
Hub Webhook을 사용하면 저장소 변경에 자동으로 반응하는 메타데이터 품질 검토 시스템을 만들 수 있어요. huggingface_hub의 ModelCard.load/DatasetCard.load로 YAML 메타데이터를 읽고, 점수·테이블 보고서를 생성해 봇 계정으로 게시하며, FastAPI 리스너를 Docker Space에 배포하고 X-Webhook-Secret으로 인증하세요. 전체 코드는 librarian-bot/webhook_metadata_reviewer Space를 참고합니다.