126 lines
8.6 KiB
Markdown
126 lines
8.6 KiB
Markdown
# WiseGrade(智评)部署与使用
|
||
|
||
WiseGrade 是单机单管理员教师端。Web 服务仅绑定 `127.0.0.1`,默认端口为 `8080`,可通过 `.env` 中的 `WISEGRADE_WEB_PORT` 修改。学生原件通过只读目录挂载进入容器,不经过浏览器上传。
|
||
|
||
## 准备
|
||
|
||
- Docker Engine + Compose v2(Linux),或 Windows Docker Desktop(WSL2 后端,运行 Linux 容器)。
|
||
- 一个存放学生材料的宿主机目录;其下每个批次目录包含 `学号_姓名_选题题目` 子目录。
|
||
- `deepseek-flash` 可访问的 OpenAI 兼容 API 地址和密钥;该端点必须支持文本与图片输入。
|
||
- 离线嵌入模型包。默认使用 BAAI/bge-m3。内存不足时可改用 BAAI/bge-small-zh-v1.5。
|
||
|
||
仓库的 `docs/` 是课程资料,不是学生原件。旧版 `.doc` 只用于课程模板,经 LibreOffice 转换;学生输入只接受 PDF、DOCX、PPTX。
|
||
LibreOffice 已安装在后端 Docker 镜像中。按本指南使用容器时,教师不需要在 Windows 或 Linux 宿主机单独安装 LibreOffice;仅在脱离容器运行后端时才需自行安装。
|
||
|
||
## Linux 启动
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
mkdir -p data/inbox data/processed data/exports models/bge-m3
|
||
```
|
||
|
||
编辑 `.env`:
|
||
|
||
```env
|
||
WISEGRADE_DATA_DIR=/absolute/path/to/WiseGradeData
|
||
DEEPSEEK_API_KEY=your-key
|
||
WISEGRADE_SECRET_KEY=用随机值替换且至少32位
|
||
EMBEDDING_MODEL_PATH=/models/bge-m3
|
||
```
|
||
|
||
也可以启动后在“模型设置”页面填写 API Key。密钥由后端加密保存,浏览器不会直接调用模型服务。`WISEGRADE_SECRET_KEY` 一旦用于加密设置,不要随意更换,否则已保存的密钥将无法解密。
|
||
|
||
```bash
|
||
docker compose up --build -d
|
||
docker compose ps
|
||
curl http://127.0.0.1:8080/api/health
|
||
```
|
||
|
||
打开 <http://127.0.0.1:8080>。`api` 启动时执行 Alembic 迁移并创建初始课程、目标、指标点和规则。评分任务由 `worker` 容器处理。
|
||
|
||
如 `8080` 端口已被占用,在 `.env` 中设置 `WISEGRADE_WEB_PORT=18080`(或其他空闲端口),重新运行 `docker compose up -d`,并使用对应端口访问。
|
||
|
||
## Windows Docker Desktop 启动
|
||
|
||
1. 安装并启动 Docker Desktop,启用 WSL2 后端,保持 Linux 容器模式。
|
||
2. 在 PowerShell 中进入项目目录:`Copy-Item .env.example .env`。
|
||
3. 编辑 `.env` 中的 `WISEGRADE_DATA_DIR`,使用正斜杠绝对路径,例如 `D:/WiseGradeData`。不要在 `.env` 中添加引号。
|
||
4. 将离线模型目录放在 `models/bge-m3`,填写 API 配置和随机 `WISEGRADE_SECRET_KEY`。
|
||
5. 运行 `docker compose up --build -d`,访问 <http://127.0.0.1:8080>。
|
||
|
||
如果挂载失败,先确认 `WISEGRADE_DATA_DIR` 存在、Docker Desktop 已取得对应磁盘访问权,再运行 `docker compose config` 查看展开后的挂载路径。首次启动后若修改了 `.env` 中的 API Key 等配置,运行 `docker compose up -d --force-recreate api worker web`,使容器读取新值。当前仓库尚未在 Windows 实机验证上述路径和文件挂载。
|
||
|
||
## 离线模型包
|
||
|
||
应用镜像不在启动时下载 BGE-M3。将独立模型包解压到 `models/bge-m3/`,目录应包含模型权重、`config.json`、分词器文件及 SentenceTransformers 配置。容器中该目录只读映射为 `/models/bge-m3`。替代模型需同时修改:
|
||
|
||
```env
|
||
EMBEDDING_MODEL_NAME=BAAI/bge-small-zh-v1.5
|
||
EMBEDDING_MODEL_PATH=/models/bge-small-zh-v1.5
|
||
EMBEDDING_MODEL_VERSION=your-package-version
|
||
```
|
||
|
||
`EMBEDDING_MODEL_VERSION` 会写入每个评分批次快照。若模型目录缺失或内容不完整,导入仍可完成,知识库入库和评分会显示错误。可离线分发 `docker save` 生成的镜像包及单独的 `models-bge-m3.tar.zst`;目标机执行 `docker load -i docker-images.tar` 后解压模型包,运行相同的 Compose 配置。
|
||
也可以把模型复制进后端镜像,但当前 Dockerfile 和 Compose 采用只读目录挂载;若改成镜像内置模型,须同时调整构建上下文,并移除会遮盖镜像内 `/models` 的挂载。本机 BGE-M3 必需文件约 2.29 GB,后端镜像当前约 1.08 GB;直接内置后镜像未压缩体积预计约 3.37 GB。API 与 worker 可以共用镜像层,不必各存一份模型。独立模型包便于单独更新和分发。
|
||
|
||
扫描 PDF 的 OCR 使用 PaddleOCR。离线 OCR 包放在 `models/ocr/detection/` 和 `models/ocr/recognition/`,或修改 `OCR_MODEL_DIR` 指向包含这两个子目录的位置。没有 OCR 模型且 PDF 无可提取文字时,文件进入解析失败状态并显示原因;系统不会在解析时自动下载 OCR 模型。
|
||
|
||
下面这组 PP-OCRv5 mobile 中文识别模型已在 PaddleOCR 3.7.0 中验证。下载后将压缩包的顶层目录去掉,使 `detection/` 和 `recognition/` 内直接包含 `inference.yml`、`inference.json` 和 `inference.pdiparams`:
|
||
|
||
```bash
|
||
mkdir -p models/ocr/detection models/ocr/recognition
|
||
curl -fL -o models/ocr/PP-OCRv5_mobile_det_infer.tar https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-OCRv5_mobile_det_infer.tar
|
||
curl -fL -o models/ocr/PP-OCRv5_mobile_rec_infer.tar https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-OCRv5_mobile_rec_infer.tar
|
||
tar -xf models/ocr/PP-OCRv5_mobile_det_infer.tar --strip-components=1 -C models/ocr/detection
|
||
tar -xf models/ocr/PP-OCRv5_mobile_rec_infer.tar --strip-components=1 -C models/ocr/recognition
|
||
```
|
||
|
||
模型名称从各自的 `inference.yml` 读取,不能让 PaddleOCR 使用与离线权重不匹配的默认模型。模型目录经 Compose 只读挂载,放入权重后无需修改 `.env`。
|
||
|
||
## 教师操作
|
||
|
||
1. 在“课程与规则”中查看初始课程版本和评分规则。已发布版本不能直接覆盖;复制草稿、编辑、保存并发布新版本。课程目标、指标点、选题方向、模板和三个 Prompt 都属于课程版本。
|
||
2. 在“知识库资料”中选课程版本并入库课程资料。入库使用本地嵌入模型和 PostgreSQL `pgvector`。
|
||
3. 在“目录扫描与导入”中浏览 `/data/inbox` 下的相对目录,选择学生总目录并扫描。修正学号、姓名、选题和材料类型;PPT 导出的 PDF 必须确认成“汇报PPT/PDF”。每类材料只选择一个文件。
|
||
4. 在“评分批次”中选择已发布课程和规则版本,创建并启动批次。每次评分建立独立批次;重试不会覆盖其他批次。
|
||
5. 在“评分与复核”中查看逐项模型原始分、原文证据、页码、页面图像和异常。教师可逐项填写分数、评语和修改说明;修改历史单独保留。
|
||
6. 在“导出任务”中按批次导出 Excel,按学生导出 PDF 反馈。缺失或无法评分的项目显示待处理,不自动补零。
|
||
|
||
成绩为阶段报告 1、2、3 各占 10%,期末占 70%。期末四项为任务完成度 20、报告规范性 20、汇报答辩 40、结果分析 20。系统的“汇报答辩”只评价 PPT 或 PPT PDF 页面内容,不评价口头答辩。
|
||
|
||
## 开发与测试(uv)
|
||
|
||
Python 依赖由 `backend/pyproject.toml` 管理:
|
||
|
||
```bash
|
||
cd backend
|
||
uv sync --extra ocr --group dev
|
||
uv run alembic upgrade head
|
||
uv run uvicorn wisegrade.main:app --reload
|
||
```
|
||
|
||
测试从仓库根目录运行:
|
||
|
||
```bash
|
||
docker compose --profile test run --build --rm test
|
||
```
|
||
|
||
测试使用独立的 PostgreSQL 16 + pgvector 容器,不连接业务数据库。每个数据库测试创建临时数据库,执行 Alembic 迁移后运行,结束时删除;`test-db` 的数据目录为 tmpfs,不会写入业务数据卷。测试会从 `.env` 读取真实 DeepSeek API Key,并加载 `models/bge-m3` 和 `models/ocr` 中的离线模型;完整流程测试会发起真实模型请求。在宿主机直接运行 `uv run pytest` 时,需先设置指向专用 `wisegrade_tests` 数据库的 `TEST_DATABASE_URL`(使用 `postgresql+psycopg` 驱动,账号需有创建数据库的权限),并提供可用的模型配置。
|
||
|
||
本地开发需提供 PostgreSQL、Redis 和与容器路径一致的挂载目录;可用 Compose 启动 `db` 和 `redis`。Vite 前端:
|
||
|
||
```bash
|
||
cd frontend
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
开发服务器将 `/api` 代理到 `localhost:8000`。集成测试从仓库 `docs/` 复制阶段报告 1、2、3 与最终报告,并生成一份汇报 PDF 测试材料。
|
||
|
||
## 故障定位
|
||
|
||
- `docker compose logs api worker` 查看迁移、解析和任务异常。日志不输出 API Key。
|
||
- 模型请求失败后按配置有限重试,评分项显示失败原因;可修复配置后重试该批次。
|
||
- 原件哈希变化后必须重新扫描并确认导入,否则解析会报“源文件已变化”。
|
||
- 源文件和模型目录为只读挂载;解析产物在 `data/processed/`,导出在 `data/exports/`,均被 Git 忽略。
|