Initial commit

This commit is contained in:
2026-06-15 09:54:01 +09:00
commit ce22ba962d
21 changed files with 3465 additions and 0 deletions

113
layoutlmv3_service.py Normal file
View File

@@ -0,0 +1,113 @@
import argparse
import gc
import os
import sys
import psutil
import uvicorn
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from loguru import logger
from starlette.responses import JSONResponse
from routers import router
app = FastAPI(title="layoutlmv3_service")
app.state.request_counter = 0
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(router)
# ── 로거 설정 ─────────────────────────────────────
logger.remove()
logger.add(
"logs/{time:YYYY-MM-DD}.log",
level="DEBUG",
rotation="00:00",
retention="30 days",
format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{function}:{line} - {message}",
)
# ── 메모리 유틸 ───────────────────────────────────
def log_memory_usage() -> float:
process = psutil.Process(os.getpid())
return process.memory_info().rss / 1024 / 1024 # MB
# ── HTTP 미들웨어 ─────────────────────────────────
@app.middleware("http")
async def log_requests(request: Request, call_next):
try:
memory_before = log_memory_usage()
request_counter = getattr(app.state, "request_counter", 0) + 1
app.state.request_counter = request_counter
logger.info(f"request_counter: {request_counter}")
logger.info(f"Received: {request.method} {request.url}")
logger.info(f"Headers: {dict(request.headers)}")
response = await call_next(request)
logger.info(f"Response status: {response.status_code}")
if request_counter % 100 == 0:
logger.info("gc.collect 실행")
gc.collect()
memory_after = log_memory_usage()
logger.info(
f"Memory: Before={memory_before:.2f}MB, "
f"After={memory_after:.2f}MB, "
f"Diff={memory_after - memory_before:.2f}MB"
)
return response
except Exception as e:
logger.exception(f"요청 처리 중 예외 발생: {e}")
return JSONResponse(
status_code=500,
content={"detail": "Internal Server Error", "error": str(e)},
)
@app.get("/", tags=["기타"])
async def root():
return {"message": "layoutlmv3 invoice classifier"}
@app.get("/health", tags=["기타"])
async def health():
import config
from utils.cache import load_cache
return {
"status": "ok",
"device": str(config.DEVICE),
"model_ready": (config.MODEL_SAVE_PATH / "config.json").exists(),
"dataset_size": len(load_cache()),
}
# ── 진입점 ────────────────────────────────────────
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("-host", default="0.0.0.0")
parser.add_argument("-port", default=10941)
parser.add_argument("-pool_size", default="10")
args = parser.parse_args()
logger.info(f"서버 시작: {args.host}:{args.port}")
uvicorn.run(
app,
host=args.host,
port=int(args.port),
limit_concurrency=1000,
timeout_keep_alive=120,
log_level="debug",
)