Flask(프론트) + FastAPI(백) + MySQL(DB) + LoRA LLM
- 자연어로 일정을 추가/수정/삭제/조회하면 캘린더와 챗봇이 동일 DB를 바라보며 즉시 동기화됩니다.
- 핵심 테이블:
users,events,chat_logs(옵션:parse_logs)
- Frontend: Flask, Bootstrap 5, FullCalendar
- Backend: FastAPI, SQLAlchemy, JWT
- DB: MySQL 8 (utf8mb4)
- LLM: Hugging Face + LoRA (
Seonghaa/CalMate-20B-KO-LoRA) 옵션
calmate/
├─ backend/ # FastAPI
│ ├─ main.py ├─ auth.py ├─ events.py ├─ chat.py
│ ├─ database.py ├─ models.py ├─ schemas.py ├─ security.py
│ ├─ llm.py (LoRA 연동) ├─ merge_lora.py (병합 스크립트)
│ └─ .env.example, requirements.txt
├─ frontend/ # Flask
│ ├─ app.py
│ ├─ templates/ (base.html, login.html, register.html, calendar.html)
│ └─ static/app.js
└─ db/schema.sql
-- MySQL 접속 후
CREATE DATABASE IF NOT EXISTS calmate DEFAULT CHARACTER SET utf8mb4;
USE calmate;
SOURCE db/schema.sql;기본 DB 비밀번호는
pass로 사용하도록 백엔드 설정되어 있습니다.
cd backend
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env
# .env에서 DB 설정 확인 (DB_PASSWORD=pass 등)
# 방법 A) 프로젝트 루트에서 실행
# uvicorn backend.main:app --reload --host 0.0.0.0 --port 8000
# 방법 B) backend 폴더에서 실행 (권장)
uvicorn main:app --reload --host 0.0.0.0 --port 8000cd ../frontend
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
# API_BASE가 기본( http://127.0.0.1:8000 )이면 바로 실행
python app.py # http://127.0.0.1:5000회원가입→ JWT 발급 → 세션 저장 → 캘린더 페이지로 이동- 캘린더에서 날짜 클릭으로 일정 생성, 드래그/리사이즈로 이동·시간 변경
- 우측 패널에서 챗봇 질의(“이번 주 일정 알려줘” 등)
LLM은 오직 아래 JSON 1개를 반환하도록 프롬프트합니다.
{"intent":"create|update|delete|query",
"title":"회의",
"start_ts":"2025-08-15 10:00",
"end_ts":"2025-08-15 11:00",
"location":"회의실 A",
"priority":"high"}create/update/delete는events에 저장/수정/삭제,query는 DB 조회 후 요약 응답.
20B급은 로컬 VRAM이 상당히 커야함. 병합은 큰 GPU에서 수행 후 병합본 폴더만 배포하는 방식을 권장합니다.
A) 병합 스크립트 --> 병합은 로컬에서 안하는걸 추천 코랩에서 하세요...
cd backend
export BASE_MODEL_ID=your/base-model
export LORA_ADAPTER_ID=Seonghaa/CalMate-20B-KO-LoRA
export HF_TOKEN=hf_xxx # private이면 필요
python merge_lora.py # 결과: backend/models_store/merged/B) 서버에서 사용
# 병합본 사용
export MERGED_MODEL_DIR=backend/models_store/merged
uvicorn main:app --host 0.0.0.0 --port 8000또는
# 병합 없이 base+LoRA 로딩(메모리 상황에 따라 실패할 수 있음)
export BASE_MODEL_ID=your/base-model
export LORA_ADAPTER_ID=Seonghaa/CalMate-20B-KO-LoRA
export LORA_MERGE_ON_START=false
export USE_8BIT=true
uvicorn main:app --host 0.0.0.0 --port 8000# backend/.env
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=pass
DB_NAME=calmate
JWT_SECRET=change-this-secret
FRONTEND_ORIGIN=http://127.0.0.1:5000
# LLM(옵션)
BASE_MODEL_ID=
LORA_ADAPTER_ID=
MERGED_MODEL_DIR=
LORA_MERGE_ON_START=true
USE_8BIT=false
HF_TOKEN=