"""Hugging Face Space — Gradio 데모 (v3, 가용성 인지 컨틴전시 정책). 재고 + 당일 업체 가용성을 입력하면 RL 에이전트가 상황별 최적 발주를 추천한다. 가용성을 바꾸면 추천 업체가 바뀌는 컨틴전시 정책을 체험할 수 있다. """ import gradio as gr from model import CONFIG, SUPPLIERS, demand_factors, load_model, recommend MODEL_PATH = "best_model_v3.pt" model = load_model(MODEL_PATH) TAU_MAX = CONFIG["tau_max"] SUP_NAMES = ["A", "B", "C", "D", "E"] def predict(on_hand, pipeline_str, day_of_year, avail_a, avail_b, avail_c, avail_d, avail_e): try: pipeline = [float(x.strip()) for x in pipeline_str.split(",") if x.strip() != ""] except ValueError: return "⚠️ 파이프라인은 숫자 콤마구분 (예: 0,0,0,0,0,0,0)" if len(pipeline) != TAU_MAX: return f"⚠️ 파이프라인은 {TAU_MAX}개 값 필요 (받음 {len(pipeline)}개)" available = [avail_a, avail_b, avail_c, avail_d, avail_e] idx, name, qty = recommend(model, float(on_hand), pipeline, int(day_of_year), available) df = demand_factors(int(day_of_year)) avail_str = ", ".join(n for n, a in zip(SUP_NAMES, available) if a) or "(전부 품절)" if idx == 0: head = "### 추천: **발주 안 함 (None)**\n가용 업체 중 발주 이득이 없거나 재고 충분." body = "" else: info = SUPPLIERS[idx] head = f"### 추천 공급업체: **{name}** · 주문량 **{qty}**" body = (f"\n- 리드타임 {info['tau']}일 · 단가 {info['P']} · MOQ {info['MOQ']}") return ( f"{head}{body}\n\n" f"> 가용 업체: **{avail_str}**\n" f"> 기대수요(오늘/3일/7일): {df[0]:.2f} / {df[1]:.2f} / {df[2]:.2f}\n" f"> 재고 {on_hand}, 연중일 {day_of_year}" ) with gr.Blocks(title="Dynamic Supplier Selection v3") as demo: gr.Markdown( "# 📦 동적 공급업체 선정 RL 에이전트 (v3)\n" "재고 + **당일 업체 가용성**을 입력하면 상황별 최적 발주를 추천합니다. " "가용성 체크를 바꿔보세요 — 1순위 업체가 품절이면 **차선책으로 자동 폴백**하는 " "컨틴전시 정책을 확인할 수 있습니다." ) with gr.Row(): with gr.Column(): on_hand = gr.Number(value=1000, label="현재 보유 재고 (on_hand)") pipeline = gr.Textbox(value="0,0,0,0,0,0,0", label=f"파이프라인 (향후 1~{TAU_MAX}일 입고예정, 콤마 {TAU_MAX}개)") day = gr.Slider(0, 364, value=150, step=1, label="연중 일자 (계절성)") gr.Markdown("**당일 업체 가용성** (체크=주문 가능)") with gr.Row(): ca = gr.Checkbox(value=True, label="A (리드7·저가)") cb = gr.Checkbox(value=True, label="B (리드5)") cc = gr.Checkbox(value=True, label="C (리드3)") cd = gr.Checkbox(value=True, label="D (리드1)") ce = gr.Checkbox(value=True, label="E (즉시·고가)") btn = gr.Button("발주 추천 받기", variant="primary") with gr.Column(): out = gr.Markdown() inputs = [on_hand, pipeline, day, ca, cb, cc, cd, ce] btn.click(predict, inputs=inputs, outputs=out) gr.Examples( examples=[ [1000, "0,0,0,0,0,0,0", 150, True, True, True, True, True], [1000, "0,0,0,0,0,0,0", 150, False, True, True, True, True], [200, "0,0,0,0,0,0,0", 100, True, True, True, True, True], [1800, "0,0,0,0,0,0,0", 100, True, True, True, True, True], ], inputs=inputs, ) if __name__ == "__main__": demo.launch()