# label-studio **Repository Path**: wanglei2jq/label-studio ## Basic Information - **Project Name**: label-studio - **Description**: 基于 HumanSignal/label-studio 的二次开发版本,在原有数据标注功能基础上增加了 超级管理员(Superuser)权限体系、多组织管理能力 和 YOLO 模型训练集成 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2026-07-29 - **Last Updated**: 2026-07-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Label Studio (改造版) 基于 [HumanSignal/label-studio](https://github.com/HumanSignal/label-studio) 的二次开发版本,在原有数据标注功能基础上增加了 **超级管理员(Superuser)权限体系**、**多组织管理能力** 和 **YOLO 模型训练集成**。 --- ## 改造内容 ### 1. 权限体系改造:超级管理员(Superuser) 原版 Label Studio 中所有已登录用户权限一致,任何用户都可以创建组织。改造后引入了 **Superuser** 角色,实现分级权限控制: | 操作 | Superuser | 普通用户 | |------|-----------|----------| | 创建组织 | ✅ | ❌ | | 查看所有组织 | ✅ | ❌(仅可见自己所属组织) | | 删除组织 | ✅(仅空组织) | ❌ | | 查看所有用户 | ✅ | ❌(仅可见本组织成员) | | 将用户添加到组织 | ✅ | ❌ | | 将用户从组织移除 | ✅ | ❌ | | 修改用户的活跃组织 | ✅ | ❌ | **后端实现:** - `core/permissions.py` — 新增 `is_superuser` 权限检查函数,将 `organizations_create` 权限覆盖为仅 Superuser 可执行,其余权限保持 `is_authenticated` - `users/api.py` — Superuser 的 `get_queryset` 返回 `User.objects.all()`,而非仅本组织用户;新增三个 Superuser 专属 API - `users/serializers.py` — Superuser 可见非本组织成员(不标记为已删除);新增 `is_superuser` 字段到用户序列化输出 ### 2. 新增 Superuser 专属 API #### 组织管理 API | 路径 | 方法 | 说明 | |------|------|------| | `/api/organizations/all` | GET | 获取所有组织列表(含成员数) | | `/api/organizations//delete` | DELETE | 删除空组织(有成员时拒绝) | | `/api/organizations/user//active-organization` | PATCH | 修改用户的活跃组织 | #### 用户-组织管理 API | 路径 | 方法 | 说明 | |------|------|------| | `/api/users//organizations/` | GET | 查看用户所属的所有组织 | | `/api/users//organizations/add/` | POST | 将用户添加到指定组织 | | `/api/users//organizations//` | DELETE | 将用户从指定组织移除 | ### 3. 前端改造 #### 新增"组织列表"页面(OrganizationListPage) - Superuser 可浏览所有组织及其成员数,可创建新组织,可删除无成员的组织 - 普通用户仅可见自己的组织 - 选中组织后右侧展示该组织成员列表 #### 新增"People"页面(PeoplePage) - 仅 Superuser 可访问(菜单栏中仅 Superuser 可见) - 全局用户列表(带搜索、分页) - 选中用户后右侧面板显示: - 用户所属组织列表(标记活跃组织) - 修改用户活跃组织的下拉选择 - 将用户添加到新组织 / 从组织移除的操作 #### 新增"创建组织"对话框(CreateOrganizationModal) - 仅 Superuser 可通过组织列表页触发 - 输入组织名称即可创建 #### 导航栏改造(Menubar) - 新增 "People" 菜单项,仅 Superuser 可见 - 原有 "Organization" 菜单项改为显示组织列表而非成员列表 ### 4. Bug 修复与健壮性增强 多处原版代码依赖 `organization.created_by` 关系访问,当 `created_by_id` 为空时会产生异常。改造后统一添加了安全检查: - `organizations/models.py` — `is_owner` 判断改用 `created_by_id` 而非 `created_by.id`,避免无创建者时的 `NoneType` 错误 - `core/feature_flags/utils.py` — 安全获取 `created_by.email` - `data_export/mixins.py` / `data_export/models.py` — 导出功能中 `access_token` 获取增加异常保护 - `jwt_auth/models.py` — JWT 权限判断改用 `created_by_id` - `organizations/serializers.py` — `OrganizationIdSerializer` 新增 `member_count` 字段 ### 5. 组织删除功能完善 `organizations/functions.py` 中的 `destroy_organization` 函数从仅删除项目扩展为完整清理: - 删除组织成员(OrganizationMember) - 删除项目(Project) - 删除转换格式(ConvertedFormat) - 删除标签(Label / LabelLink) - 删除 Webhook - 删除 ML 相关对象(ModelInterface / ThirdPartyModelVersion / ModelRun / ModelProviderConnection) - 删除会话策略(SessionTimeoutPolicy) - 删除 SAML / JWT 配置 - 置空指向该组织的用户的 `active_organization` - 最终删除组织本身 ### 6. YOLO 模型训练集成 集成 `cv-ultralytics` 训练引擎,在标注平台内直接训练 YOLO 模型: - **入口**:Projects 列表页 **Train** → `/projects/train`(全局训练,不挂在单个项目内) - **多项目训练集**:可勾选多个项目合并导出后一起训练(各类别须与配置 `classes` 一致) - **任务驱动**:每次启动产生一条训练任务,进度 / 日志 / 报错 / 模型下载均在任务详情中查看 - **配置管理**:独立「配置管理」页,支持完整 YOLO 超参;启动时可选择 YOLO 版本(v5/v8/v9/v10)与尺寸档位(任务类型由配置自动带出) - **自动数据流转**:导出 YOLO 格式 → 划分数据集 → 生成 `data.yaml` → 训练 - **数据划分**:与 `cv-ultralytics` 原仓库一致 — **训练集 80% / 验证集 15% / 测试集 5%** - **预训练权重**:本地 `cv-ultralytics/.../models/` 有对应 `.pt` 则直接用,否则走国内镜像竞速下载 - **产物**:可下载 `best.pt` / `last.pt`,并展示 F1 等训练曲线(若生成) - **训练调度**:标注端导出后按「训练机」**SSH 派发**到 GPU 机执行(也支持同机 `--profile gpu` 的 RQ Worker) - **GPU 支持**:训练在 GPU 机;标注端 `app` 无需 GPU - **多训练机**:Train → 训练机 填写 IP / SSH,测试连接后开训可选机器 支持的训练任务类型: - `obb`:旋转边界框检测(Oriented Bounding Box) - `detect`:标准目标检测 - `cls`:图像分类(需 Choices 标注) - `seg`:实例分割(需 PolygonLabels) --- ## 怎么跑起来(看这一节就够) | 我现在… | 看下面 | |---------|--------| | **部署标注端(网页 / 数据 / DB,Docker)** | **① 标注端 Docker(推荐)** | | 自己电脑改代码 | **② 本地开发** | | **部署 GPU 训练端** | **③ 训练端部署(本文)** | 用的时候:浏览器打开网页 → Projects → **Train** → 选项目 / 训练机开训 → 下载模型。 **角色约定:** | 端 | 职责 | 要不要 GPU | |----|------|------------| | **A 标注端** | 网页、Postgres、Redis、导出数据包、派发任务 | 否 | | **B 训练端** | 收包、YOLO 训练、回传 `best.pt` | 是 | --- ### ① 标注端 Docker(推荐生产用法) 标注端 **不需要 GPU**。 #### 目录 ```text label-studio/ ← 仓库根目录 ├── docker-compose.yml ├── .env.example ← 复制成 .env 再填 ├── .env ← 本机配置(勿提交) ├── mydata/ ← 数据 / 媒体 / SSH 密钥(自动出现) ├── postgres-data/ ├── redis-data/ └── cv-ultralytics/ ← 可空目录挂载;真正训练在 GPU 机 ``` #### 配置(先空着,由部署同事填写) ```bash cp .env.example .env # 编辑 .env,至少填下面两项(当前仓库里刻意留空): # LABEL_STUDIO_HOST= # 对外访问地址,如 http://<待填>:8080 # TRAINING_A_BIND_HOST= # 训练机连回标注端的内网 IP,如 10.x.x.x ``` `.env.example` 里其余训练相关项也可保持空;默认 `TRAINING_DATA_MODE=ssh`,由页面「训练机」SSH 派发,**不必**在标注端起 `training-worker`。 #### 启动(复制执行) ```bash cd /path/to/label-studio # 1)准备配置 cp -n .env.example .env # 填写 LABEL_STUDIO_HOST、TRAINING_A_BIND_HOST 后再上线 # 2)确保数据目录可被容器用户写入(镜像内 uid 1001) mkdir -p mydata postgres-data redis-data cv-ultralytics chown -R 1001:0 mydata || true # 3)只起标注端(nginx + app + db + redis),不要加 --profile gpu docker compose --env-file .env up -d --build nginx app db redis # 4)首次:迁移 + 管理员 docker compose --env-file .env run --rm app \ python3 /label-studio/label_studio/manage.py migrate docker compose --env-file .env run --rm app \ python3 /label-studio/label_studio/manage.py createsuperuser ``` 浏览器打开:`http://`(默认映射宿主机 **8080**)。 #### 开训前在网页里做的事 1. **Train → 训练机**:填训练机内网 IP、SSH 用户、密码 → 测试连接(成功后密码不落库,密钥在 `mydata/ssh/`)。 2. **Train → 开始训练**:选项目、配置、训练机后开训。 标注端容器需能访问训练机 `IP:22`;训练机需能访问标注端 **5432 / 6379**(compose 已暴露,防火墙放行由部署同事处理)。 #### 更新标注端 ```bash git pull docker compose --env-file .env up -d --build nginx app db redis docker compose --env-file .env run --rm app \ python3 /label-studio/label_studio/manage.py migrate ``` #### 可选:同机带 GPU 的 RQ Worker 仅当标注和训练在同一台 Docker 主机、且要用共享盘模式时: ```bash # 先把 .env 里 TRAINING_DATA_MODE=shared docker compose --env-file .env --profile gpu up -d training-worker ``` 多机 SSH 派发场景 **不要** 启用。 --- ### ② 本地开发(自己电脑) ```bash TRAINING_EXECUTOR=local TRAINING_DATA_MODE=shared ``` ```bash pip install poetry poetry install pip install torch torchvision ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple DJANGO_DB=sqlite DJANGO_SETTINGS_MODULE=core.settings.label_studio \ poetry run python label_studio/manage.py migrate DJANGO_DB=sqlite DJANGO_SETTINGS_MODULE=core.settings.label_studio \ poetry run python label_studio/manage.py createsuperuser TRAINING_EXECUTOR=local TRAINING_DATA_MODE=shared make run-dev ``` 浏览器:`http://localhost:8080`。改前端后再:`cd web && yarn install && yarn run build`。 --- ### ③ 训练端部署(GPU 机) 训练端有两种用法,**不要混用同一台机的两套调度**: | 模式 | 谁拉起训练 | B 要不要常驻进程 | 推荐 | |------|------------|------------------|------| | **A. 页面 SSH 派发(默认)** | A 经 SSH 在 B 上跑 `python -m training.remote_runner` | **不必**常驻 Worker;装好环境即可 | ✅ 推荐 | | **B. RQ Worker** | B 常驻 `rqworker training` 听 Redis | 要常驻 | 备选 | --- #### ③-A 推荐:页面 SSH 派发(conda) 流程:网页「训练机」填 B 的 IP/账号/密码 → 测试连接(A 把公钥写入 B)→ 开训时 A 把 `export.zip` scp 到 B → SSH 执行 `training.remote_runner` → 训完后 B 再把产物 scp 回 A。 ##### 1)目录(B 上) 路径须与网页「训练机 → 代码目录」一致(默认如下): ```text /root/label-studio/ # 或 /root/label-stdio,与页面 remote_root 一致 ├── label_studio/ # Django 后端(含 training/) ├── cv-ultralytics/ # YOLO 引擎 + 预训练权重/runs │ ├── ultralytics/ │ └── ... └── mydata/ # 自动出现:收包、解压、临时产物 └── media/training_xfer/job_/ ``` ```bash # 示例:克隆到默认路径 git clone <本仓库地址> /root/label-studio cd /root/label-studio # 确保 cv-ultralytics 齐全(权重可首次训练时再下) ``` ##### 2)Python 环境(B 上,CentOS7 / glibc 2.17 注意用 conda 装二进制) A 端派发脚本会尝试:`conda activate lable` 或 `conda activate label-studio`。 **请把环境建成这两个名字之一**(推荐 `lable`,与现网一致)。 ```bash source /root/miniforge3/etc/profile.d/conda.sh # 按实际 conda 路径改 conda create -n lable python=3.11 -y conda activate lable # 易编译失败的包优先 conda conda install -y "numpy>=2.2.6,<3" pandas pillow contourpy matplotlib \ gxx_linux-64 gcc_linux-64 -c conda-forge # CUDA 版 PyTorch(驱动 12.x 可用 cu118) pip install torch torchvision \ --index-url https://download.pytorch.org/whl/cu118 \ --extra-index-url https://pypi.tuna.tsinghua.edu.cn/simple pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple # 安装本仓库(Label Studio + training) cd /root/label-studio pip install -e . -i https://pypi.tuna.tsinghua.edu.cn/simple # 若再卡编译:对该包 conda install -y <包名> -c conda-forge 后重试 # 验证 python -c "import torch,django,ultralytics; print(torch.__version__, torch.cuda.is_available(), django.__version__)" ``` AMP 检查还需要样例图(路径多一层 `ultralytics`): ```bash mkdir -p cv-ultralytics/ultralytics/ultralytics/assets # 若仓库已有 cv-ultralytics/ultralytics/assets/bus.jpg: cp -n cv-ultralytics/ultralytics/assets/bus.jpg \ cv-ultralytics/ultralytics/ultralytics/assets/bus.jpg ``` ##### 3)系统与网络(B 上) ```bash # SSH 服务(给 A 登录) systemctl enable --now sshd # 或 ssh # 防火墙:允许 A 访问 22;B 需能访问 A 的 5432、6379、以及回传用的 22 ``` | 方向 | 端口 | 用途 | |------|------|------| | A → B | 22 | 测连通、推包、拉起 `remote_runner` | | B → A | 5432 / 6379 | 读写训练任务状态 | | B → A | 22 | 训完 scp 回传 `best.pt`(B 需有能登 A 的密钥,或由运维配好) | ##### 4)在 A 网页登记训练机 1. 打开 **Train → 训练机** 2. 填写:显示名、**内网 IP**、SSH 用户、密码、**代码目录**(如 `/root/label-studio`) 3. **测试连接**(成功后公钥写入 B,密码不落库) 4. 开训:选项目 + 配置 + 该训练机 A 的 `.env` 须已填 `TRAINING_A_BIND_HOST=`,否则远程环境里的 `POSTGRE_HOST` / `REDIS_HOST` 可能不对。 ##### 5)日志与产物(B 上) ```bash # 某次任务日志(A 派发后生成) tail -f /root/label-studio/mydata/media/training_xfer/job_/remote_train.log # 训练过程目录 ls /root/label-studio/cv-ultralytics/runs/job_/ # 预训练权重(会保留) ls /root/label-studio/cv-ultralytics/ultralytics/ultralytics/models/ ``` 训完后:临时 `export.zip` / 划分数据集一般会清掉;`best.pt` 等回传到 A 的 `mydata/media/training_xfer/job_/artifacts/`,网页可下载。 ##### 6)本模式要不要「启动服务」? **不要**为 SSH 派发单独起常驻 `rqworker`。 环境装好、sshd 开着即可;真正训练进程由 A 临时拉起 `training.remote_runner`。 --- #### ③-B 备选:本机常驻 RQ Worker(conda) 适用:不走页面 SSH 派发,B 自己听 Redis `training` 队列。 与 ③-A **不要**在同一台机同时当默认调度方式混用而不加说明。 ```bash # 1)同 ③-A 装好 conda 依赖与代码 # 2)准备 SSH 私钥(Worker 从 A 拉包 / 回传),例如: mkdir -p /root/label-studio/ssh # 放入能登录 A 的私钥 → ./ssh/id_rsa ,chmod 600 # A 的 authorized_keys 需包含对应公钥 # 3)启动(可参考仓库根目录 start-training-worker.sh,按实际路径改) cd /root/label-studio export DJANGO_DB=default export DJANGO_SETTINGS_MODULE=core.settings.label_studio export POSTGRE_HOST= export POSTGRE_NAME=postgres export POSTGRE_USER=postgres export POSTGRE_PASSWORD= export POSTGRE_PORT=5432 export REDIS_HOST= export REDIS_PORT=6379 export TRAINING_DATA_MODE=ssh export TRAINING_SSH_HOST= export TRAINING_SSH_USER=root export TRAINING_SSH_KEY=/root/label-studio/ssh/id_rsa export TRAINING_SSH_REMOTE_DATA=/root/label-studio/mydata # A 宿主机 mydata 绝对路径 export CV_ULTRA_PATH=/root/label-studio/cv-ultralytics # 使用你的 conda 环境里的 python python label_studio/manage.py rqworker training ``` 后台示例: ```bash nohup python label_studio/manage.py rqworker training \ > /root/label-studio/training-worker.log 2>&1 & tail -f /root/label-studio/training-worker.log ``` A 端此时应使用 RQ 入队(`TRAINING_EXECUTOR=rq`),且训练机节点模式与队列名一致。 --- #### ③-C 备选:Docker 训练 Worker ```bash cd /root/label-studio # 前置 # 1)安装 NVIDIA Container Toolkit,并确认:docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi # 2)./ssh/id_rsa 存在且能 SSH 登录 A;A 防火墙放行 5432/6379 # 3)./cv-ultralytics 齐全 export POSTGRE_HOST= export REDIS_HOST= export TRAINING_DATA_MODE=ssh export TRAINING_SSH_HOST= export TRAINING_SSH_USER=root export TRAINING_SSH_KEY=/ssh/id_rsa export TRAINING_SSH_REMOTE_DATA=/root/label-studio/mydata # A 宿主机路径 docker compose -f docker-compose.training.yml up -d --build docker compose -f docker-compose.training.yml logs -f training-worker ``` 注意: - 首次 `--build` 较久;若 yarn 缓存损坏导致前端构建失败,清理 BuildKit 缓存后重试。 - 未装 **nvidia-container-toolkit** 时容器内无 GPU,不能训。 - 与「页面 SSH 派发」勿混用同一套未说明的环境。 --- #### ③ 训练端检查清单 | 项 | SSH 派发 (③-A) | RQ / Docker (③-B/C) | |----|----------------|---------------------| | 代码目录与页面一致 | ✅ | ✅ | | conda + torch(CUDA) + ultralytics + 本仓库 | ✅ | ✅ | | `cv-ultralytics` + `assets/bus.jpg`(AMP) | ✅ | ✅ | | sshd / A→B:22 | ✅ | 按需 | | B→A:5432、6379 | ✅(remote_runner 写库) | ✅ | | B→A SSH 回传密钥 | ✅(训完 scp) | ✅(Worker scp) | | 常驻 `rqworker` | ❌ 不需要 | ✅ 需要 | | A `.env` 中 `TRAINING_A_BIND_HOST` | ✅ | 按需 | --- ### 出问题先看这 | 现象 | 怎么办 | |------|--------| | 网页起不来 | `docker compose ps` / `docker compose logs app nginx` | | 测试连接失败 | 容器能否访问训练机 22 端口;密码是否正确;镜像是否含 paramiko(需 `--build`) | | 下拉里一直「离线」 | 与顶部状态不一致时强刷;「离线」= 训练进程未跑,SSH 通会显示「SSH已通」 | | 本地点训练没反应 | 确认 `TRAINING_EXECUTOR=local` | | `mydata/ssh` 写不了 | `chown -R 1001:0 mydata` | | 训练失败缺 `bus.jpg` | 拷到 `cv-ultralytics/ultralytics/ultralytics/assets/bus.jpg` | | AMP 慢 / 反复下 `yolov8n.pt` | 文件落在进程 CWD;可事先放到启动目录 | | Docker 无 GPU | 安装 nvidia-container-toolkit 并重启 dockerd | | RQ Worker 起不来 | 检查 `POSTGRE_HOST` / `REDIS_HOST` 是否指向 A 且端口通 | | SSH 派发后 B 无进程 | 看 `mydata/media/training_xfer/job_*/remote_train.log`;确认 conda 名为 `lable` 或 `label-studio` | --- ## 更新项目 当仓库有新代码推送后,按以下步骤更新: ```bash # 1. 拉取最新代码 git pull # 2. 标注端 Docker:重新构建并启动(前端变更会在镜像构建时打包) docker compose --env-file .env up -d --build nginx app db redis # 3. 运行数据库迁移(training 等新表/字段变更时必须执行) docker compose --env-file .env run --rm app \ python3 /label-studio/label_studio/manage.py migrate ``` **本地开发 / 非 Docker 更新:** ```bash # 1. 拉取最新代码 git pull # 2. 更新 Python 依赖(如果 pyproject.toml 有变化) poetry install # 若训练依赖有变,再确认 torch / ultralytics: # pip install torch torchvision --index-url https://mirror.sjtu.edu.cn/pytorch-wheels/cu118 # pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple # 3. 更新并构建前端(TrainingPage / ApiConfig 等变更后必须 build) cd web && yarn install && yarn run build && cd .. # 4. 运行数据库迁移 poetry run python label_studio/manage.py migrate # 5. 重启后端服务 make run-dev ``` > **注意**:每次更新后务必执行迁移;有前端改动时务必 `yarn build`,否则训练页/配置保存等新功能不会生效。 --- ## 生产打包 / 发布 推荐把 **Docker 镜像** 作为生产环境交付物。这个仓库根目录下的 `Dockerfile` 已经包含前端生产构建、Python 依赖安装、`collectstatic` 和最终运行镜像封装,因此生产打包命令直接使用: ```bash docker build -t /label-studio: . ``` 例如: ```bash docker build -t registry.example.com/label-studio:2026.05.06 . docker push registry.example.com/label-studio:2026.05.06 ``` 如果只是想单独验证构建产物,也可以使用下面两个子命令: ```bash # 仅构建前端生产包 make frontend-build # 仅构建 Python 分发包(wheel / sdist) poetry build ``` --- ## 创建 Superuser 首次部署后需通过 Django 管理命令创建 Superuser: ```bash # Docker Compose 环境 docker compose run app python3 /label-studio/label_studio/manage.py createsuperuser # 本地开发环境 poetry run python label_studio/manage.py createsuperuser ``` 创建的 Superuser 即可使用上述所有管理功能。 --- ## 新增 API 快速参考 ### 获取所有组织 ```bash curl -H "Authorization: Token " \ http://localhost:8080/api/organizations/all ``` ### 创建组织 ```bash curl -X POST -H "Authorization: Token " \ -H "Content-Type: application/json" \ -d '{"title": "New Org"}' \ http://localhost:8080/api/organizations ``` ### 删除空组织 ```bash curl -X DELETE -H "Authorization: Token " \ http://localhost:8080/api/organizations/1/delete ``` ### 查看用户所属组织 ```bash curl -H "Authorization: Token " \ http://localhost:8080/api/users/3/organizations/ ``` ### 将用户添加到组织 ```bash curl -X POST -H "Authorization: Token " \ -H "Content-Type: application/json" \ -d '{"organization_id": 2}' \ http://localhost:8080/api/users/3/organizations/add/ ``` ### 将用户从组织移除 ```bash curl -X DELETE -H "Authorization: Token " \ http://localhost:8080/api/users/3/organizations/2/ ``` ### 修改用户活跃组织 ```bash curl -X PATCH -H "Authorization: Token " \ -H "Content-Type: application/json" \ -d '{"active_organization": 2}' \ http://localhost:8080/api/organizations/user/3/active-organization ``` ### 获取训练模型配置列表 ```bash curl -H "Authorization: Token " \ http://localhost:8080/api/train/configs ``` ### 查询可选预训练权重(按任务类型 / YOLO 版本) ```bash curl -H "Authorization: Token " \ "http://localhost:8080/api/train/weights?task_type=obb&version=8" ``` ### 启动训练(多项目) ```bash curl -X POST -H "Authorization: Token " \ -H "Content-Type: application/json" \ -d '{ "config_name": "tree-obb", "project_ids": [1, 2], "yolo_version": "8", "yolo_scale": "x", "train_params": {"epochs": 1000, "batch": 16} }' \ http://localhost:8080/api/train ``` ### 训练任务列表 / 详情 ```bash curl -H "Authorization: Token " \ http://localhost:8080/api/train/jobs curl -H "Authorization: Token " \ http://localhost:8080/api/train/jobs/1 ``` --- ## 项目结构 ``` label-studio/ ├── cv-ultralytics/ # ✨ YOLO 训练引擎(仅保留平台用到的子集) │ ├── datasets_process/utils/group_img.py # ✨ 数据集划分 │ └── ultralytics/ # YOLO 框架源码 ├── label_studio/ # Django 后端 │ ├── core/ │ │ ├── permissions.py # ✏️ 权限体系改造(Superuser 权限) │ │ └── feature_flags/utils.py # ✏️ 安全修复 │ ├── organizations/ │ │ ├── api.py # ✏️ 新增 3 个 Superuser API │ │ ├── urls.py # ✏️ 新增路由 │ │ ├── serializers.py # ✏️ 新增 member_count 字段 │ │ ├── models.py # ✏️ is_owner 修复 │ │ ├── functions.py # ✏️ destroy_organization 完整清理 │ │ └── views.py # ✏️ 使用 react_page.html │ │ └── templates/ # ✨ 新增 react_page.html │ ├── users/ │ │ ├── api.py # ✏️ 新增 3 个 Superuser API + queryset 扩展 │ │ ├── urls.py # ✏️ 新增路由 │ │ └── serializers.py # ✏️ is_superuser 字段 + Superuser 可见性 │ ├── data_export/ │ │ ├── mixins.py # ✏️ access_token 安全获取 │ │ ├── models.py # ✏️ access_token 安全获取 │ ├── jwt_auth/models.py # ✏️ created_by_id 修复 │ ├── training/ # ✨ 训练模块 │ │ ├── api.py # ✨ 训练 API(导出后 RQ 入队 / 本机回退) │ │ ├── rq_jobs.py # ✨ RQ Worker 入口(build_dataset + run_training) │ │ ├── jobs.py # ✨ rq_jobs 别名(分机方案) │ │ ├── transfer.py # ✨ 共享盘 / 内网拉包与产物回传 │ │ ├── paths.py # ✨ 共享盘路径约定(DATA_ROOT / CV_ULTRA) │ │ ├── models.py # ✨ 训练任务、模型配置、训练日志、训练模型 │ │ ├── tasks.py # ✨ 数据集划分 + YOLO 训练执行 │ │ ├── weights.py # ✨ 预训练权重命名 / 国内镜像下载 │ │ ├── urls.py # ✨ 训练模块路由 │ │ └── migrations/ # ✨ 数据库迁移(0001–0006) │ └── ... ├── web/ # React 前端 │ ├── apps/labelstudio/src/ │ │ ├── components/Menubar/ # ✏️ 新增 People 菜单项(Superuser 限定) │ │ ├── config/ApiConfig.js # ✏️ 新增 API 路由配置 │ │ ├── pages/ │ │ │ ├── Organization/ │ │ │ │ ├── OrganizationListPage/ # ✨ 新增组织列表页 │ │ │ │ └── PeoplePage/ │ │ │ │ ├── CreateOrganizationModal.tsx # ✨ 新增创建组织对话框 │ │ │ │ ├── PeopleListTable.jsx # ✨ 新增全局用户列表 │ │ │ │ ├── SelectedUserPanel.jsx # ✨ 新增用户组织管理面板 │ │ │ │ ├── PeopleList.jsx # ✏️ 改造为支持 organizationId │ │ │ │ └── PeoplePage.jsx # ✏️ 改造为 Superuser 限定 │ │ │ └── index.js # ✏️ 注册 PeoplePage、TrainingPage 路由 │ │ │ └── TrainingPage/ # ✨ 训练页面 │ │ │ ├── TrainingPage.jsx # ✨ 训练页面组件 │ │ │ └── TrainingPage.scss # ✨ 训练页面样式 │ ├── libs/core/src/types/user.ts # ✏️ 新增 is_superuser 类型 │ └── ... ├── docker-compose.yml # app + redis + training-worker(GPU) ├── docker-compose.training.yml # ✨ 仅 GPU 训练服 RQ Worker ├── Dockerfile # 生产镜像构建(已包含 YOLO 训练依赖) ├── Dockerfile.development # 开发镜像构建 ├── Makefile # 开发快捷命令 ├── pyproject.toml # Python 项目配置(训练用 torch/ultralytics 需额外 pip) └── ... ``` 标注说明:✏️ = 修改已有文件,✨ = 新增文件 --- ## 与原版的差异总结 | 维度 | 原版 Label Studio | 本改造版 | |------|-------------------|----------| | 组织创建 | 任何用户可创建 | 仅 Superuser 可创建 | | 组织删除 | 不支持 | Superuser 可删除空组织 | | 组织列表 | 仅见自己所属 | Superuser 可见全部(含成员数) | | 用户管理 | 仅管理本组织成员 | Superuser 可管理所有用户 | | 用户-组织关系 | 无法跨组织操作 | Superuser 可添加/移除用户到任意组织 | | 活跃组织切换 | 仅用户自己 | Superuser 可为任意用户切换 | | 导航菜单 | Organization = 成员列表 | Organization = 组织列表 + People(Superuser) | | YOLO 训练 | 无 | Projects 级多项目训练 + 任务/配置/权重管理 | --- ## License 基于原版 [Apache 2.0 LICENSE](/LICENSE) © [Heartex](https://www.heartex.com/)。2020-2025