Webhook 가이드: 데이터셋이 바뀌면 모델을 자동 재학습하는 시스템

Webhook 가이드: 데이터셋이 바뀌면 모델을 자동 재학습하는 시스템

HF Datasets, Webhooks, Spaces, AutoTrain을 사용해 Hugging Face 플랫폼에서 자동 학습 파이프라인을 설정하는 방법을 안내하는 가이드예요.

출처: 문서

본문

이미지 분류 데이터셋의 변경을 듣고, AutoTrain으로 microsoft/resnet-50의 파인튜닝을 트리거하는 Webhook을 만들 거예요.

전제: 데이터셋을 Hub에 업로드

예시를 위해 간단한 이미지 분류 데이터셋을 사용할게요. Hub에 데이터 업로드 방법은 여기에서 자세히 확인할 수 있어요.

dataset

데이터셋 변경에 반응하는 Webhook 만들기

먼저 설정에서 Webhook을 만들어요.

  • 대상 저장소로 데이터셋을 선택해요. 이 예시에서는 huggingface-projects/input-dataset을 대상으로 해요.
  • 지금은 더미 Webhook URL을 넣어도 돼요. Webhook을 정의하면 전송될 이벤트를 볼 수 있어요. 디버깅에 유용한 재생(replay)도 가능해요!
  • 더 안전하게 만들기 위해 시크릿을 입력해요.
  • 데이터 변경에 반응하려고 하니 "Repo update" 이벤트를 구독해요.

Webhook은 이렇게 생겼어요.

webhook-creation

Webhook에 반응하는 Space 만들기

이제 Webhook 이벤트에 반응하는 방법이 필요해요. 쉬운 방법은 Space를 사용하는 거예요!

예시 Space는 여기에서 찾을 수 있어요.

이 Space는 Docker, Python, FastAPI, uvicorn으로 간단한 HTTP 서버를 실행해요. Docker Spaces에 대해 더 자세히 알아보려면 여기를 읽어보세요.

진입점은 src/main.py예요. 이 파일을 살펴보며 무슨 일을 하는지 자세히 볼게요.

  1. /webhook에서 HTTP POST 요청을 수신하는 FastAPI 앱을 생성해요.
from fastapi import FastAPI

# [...]
@app.post("/webhook")
async def post_webhook(
	# ...
):

# ...
  1. 이 라우트는 X-Webhook-Secret 헤더가 존재하고 그 값이 Webhook 설정에 지정한 값과 같은지 확인해요. WEBHOOK_SECRET 시크릿은 Space 설정에 설정되어 있어야 하고 Webhook에 설정한 시크릿과 같아야 해요.
# [...]

WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET")

# [...]

@app.post("/webhook")
async def post_webhook(
	# [...]
	x_webhook_secret:  Optional[str] = Header(default=None),
	# ^ checks for the X-Webhook-Secret HTTP header
):
	if x_webhook_secret is None:
		raise HTTPException(401)
	if x_webhook_secret != WEBHOOK_SECRET:
		raise HTTPException(403)
	# [...]
  1. 이벤트의 페이로드는 JSON으로 인코딩돼요. 여기서는 pydantic 모델로 이벤트 페이로드를 파싱할 거예요. Webhook을 다음 조건에서만 실행하도록 지정해요.
  • 이벤트가 입력 데이터셋에 관한 것
  • 이벤트가 저장소 콘텐츠의 업데이트, 즉 새 커밋이 있는 것
# defined in src/models.py
class WebhookPayloadEvent(BaseModel):
	action: Literal["create", "update", "delete", "move"]
	scope: str

class WebhookPayloadRepo(BaseModel):
	type: Literal["dataset", "model", "space"]
	name: str
	id: str
	private: bool
	headSha: str

class WebhookPayload(BaseModel):
	event: WebhookPayloadEvent
	repo: WebhookPayloadRepo

# [...]

@app.post("/webhook")
async def post_webhook(
	# [...]
	payload: WebhookPayload,
	# ^ Pydantic model defining the payload format
):
	# [...]
	if not (
		payload.event.action == "update"
		and payload.event.scope.startswith("repo.content")
		and payload.repo.name == config.input_dataset
		and payload.repo.type == "dataset"
	):
		# no-op if the payload does not match our expectations
		return {"processed": False}
	#[...]
  1. 페이로드가 유효하면 다음 단계는 AutoTrain에 프로젝트를 만들고, 입력 데이터셋에서 입력 모델(microsoft/resnet-50)의 파인튜닝을 예약하고, 완료되면 데이터셋에 discussion을 만드는 거예요!
def schedule_retrain(payload: WebhookPayload):
	# Create the autotrain project
	try:
		project = AutoTrain.create_project(payload)
		AutoTrain.add_data(project_id=project["id"])
		AutoTrain.start_processing(project_id=project["id"])
	except requests.HTTPError as err:
		print("ERROR while requesting AutoTrain API:")
		print(f"  code: {err.response.status_code}")
		print(f"  {err.response.json()}")
		raise
	# Notify in the community tab
	notify_success(project["id"])

코멘트 안의 링크를 방문해 학습 비용 견적을 확인하고 모델 파인튜닝을 시작하세요!

community tab notification

이 예시에서는 Hugging Face AutoTrain으로 모델을 빠르게 파인튜닝했지만, 당연히 자신의 학습 인프라를 연결할 수도 있어요!

마음껏 Space를 개인 네임스페이스에 복제하고 가지고 놀아보세요. 두 가지 시크릿을 제공해야 해요.

또한 원하는 데이터셋과 모델을 쓰려면 config.json 파일을 조정해야 해요.

{
	"target_namespace": "the namespace where the trained model should end up",
	"input_dataset": "the dataset on which the model will be trained",
	"input_model": "the base model to re-train",
	"autotrain_project_prefix": "A prefix for the AutoTrain project"
}

Webhook이 이벤트를 Space로 보내도록 설정

마지막으로 Webhook이 Space에 POST 요청을 보내도록 구성해야 해요.

먼저 컨텍스트 메뉴에서 Space의 "direct URL"을 가져와요. "Embed this Space"를 클릭하고 "Direct URL"을 복사하세요.

embed this Space

direct URL

Webhook을 업데이트해 그 URL로 요청을 보내게 하세요.

webhook settings

이제 끝이에요! 이제 입력 데이터셋에 커밋이 생길 때마다 AutoTrain으로 ResNet-50의 파인튜닝이 트리거돼요 🎉

더 알아보기 (Learn more)

Webhook으로 데이터셋의 repo.content 업데이트를 감지하고, Space의 FastAPI 서버가 X-Webhook-Secret을 검증한 뒤 AutoTrain 프로젝트를 만들어 파인튜닝을 예약해요. Space를 복제할 때는 WEBHOOK_SECRETHF_ACCESS_TOKEN(write 권한) 두 시크릿과 config.json만 맞춰주면 나만의 자동 재학습 파이프라인이 완성돼요.