Files
2026-09-11 10:45:04 +08:00

194 lines
16 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 视野后端配置
server:
address: ":8080"
openapiPath: "/api.json"
# 请求体上限(默认 8MB):APK 上传(管理端下发新版本)可能数百 MB,必须放大
clientMaxBodySize: "512mb"
database:
default:
type: pgsql
# PostgreSQL 连接(分字段写法规避密码特殊字符的 URL 转义问题)。
# 下面是本地开发默认值;服务器部署由 docker-compose 只注入 DB_HOST=postgres(容器名直连),
# 库名等其余项两边一致直接用这里的默认值。见 common/config_env.go(支持 DB_HOST/DB_NAME/
# DB_PORT/DB_USER/DB_PASS 五项,按需注入)。
host: "127.0.0.1"
port: "5432"
user: "259278618@qq.com"
pass: "Tongli686^*^"
name: "animal_spot"
cache:
# 查询缓存 TTL(秒)
ttl: 30
auth:
# 登录 token 签名密钥(HMAC-SHA256,必填):换值即全员下线
secret: "changeme-auth-secret"
# 登录 token 有效期(秒),默认 30 天
tokenTtl: 2592000
admin:
# 后台管理端静态 token:请求头 X-Admin-Token 必须匹配;为空时管理接口全部拒绝
token: "Tongli686^*^"
app:
# Android APK 上传目录(运行时数据,与 ./data 平级、docker-compose 挂载持久化;
# 目录下永远只保留最新一个文件 observer-latest.apk,下载地址固定 /download/observer-latest.apk
apkDir: "./workspace"
# 模型训练体系运行时数据根目录(图片/标注/模型/训练产物;与 apkDir 同目录时共用 workspace
datasetDir: "./workspace"
# 图像生成(管理端「AI 生成图片」):provider 必填项缺失时生成接口返回「图像生成服务未配置」
imageGen:
provider: localai # dashscope | localai
baseUrl: "http://192.168.3.210:18080" # localai 必填:本机 local-ai 地址(/v1/images/generations
model: z-image-turbo # localai 上加载的模型名;dashscope 用 qwen-image-3.0
apiKey: "" # dashscope 必填:DashScope API Key
poolSize: 1 # 生成任务并发度(z-image 显存独占,默认 1)
# 通用提示词模板:{species} 取数据集 gen_species(单值,空回退数据集名);{count} 为数量词
# (固定 "1只",每张仅 1 个目标;原表单数量选择已取消);{scene}/{action}/{light} 池内随机
# scene/action/occlusion 从数据集表 gen_scenes/gen_actions/gen_occlusions 池随机,无 config 兜底;
# gen_scenes 条目兼容捆绑组对象 {scene,weight,actions,occlusions,position}——选中时动作/遮挡组内联动,
# position 覆盖默认位置锚(树栖场景须把目标锚到枝头,默认地平线锚只适合地面/水面),
# 见技术设计.md「场景捆绑组+权重」,斑鸠 80% 树上场景即此机制);
# {tone} 取数据集表 gen_tone(默认深色,白化个体配浅色);{sizeHint} 按数据集表 gen_heights 站高与
# 表单距离算出像素高,按画面占比分级尺寸词(像素数与固定物体类比词均不通用,2026-08-31)+ 占比。物种只写名字
# 不写羽毛细节(细节会把镜头拉近,详见技术设计)。引导语「手机原相机主摄不变焦」(2026-08-31 v4 定案):
# 与 13px 像素数学完全自洽(公式即按主摄 vfov 52° 计算);手机拍远处目标天然显小(先验同向);
# 顺带对齐推理端域(App 就是手机拍摄)。演进:广角(前景大主体先验)→ 长焦(物理放大)→ 全删 → 手机主摄不变焦。
# 拍摄角度描述(仰/俯/平)仍不带;位置锚 {position}(默认「在{distanceWord}的地平线附近」,地平线=远景场景锚点,
# 适合地面/水面;捆绑组 position 可覆盖为枝头/树冠锚——2026-09-04,树栖目标锚在地平线上语义落地);
# 动作/遮挡在普通模板中位于目标之后(动作=叙事焦点=视觉焦点,降级处理)
promptTemplate: "野外大远景实拍:手机原相机主摄不变焦,{scene}{position}有且仅有{count}{species}{sizeHint}{occlusion}{species}在{action},只是很小的{tone}轮廓,隐约可辨,画面绝大部分是{scene},没有任何靠近镜头的动物,{light},写实野外摄影,真实照片质感"
# 远景小目标模板(代码按尺寸占比 <2% 切换):目标小到动作/遮挡/性别细节无法呈现,保留细节描写会
# 迫使模型把目标画大(2026-08-31 实测两次失败后定案)——只留「远到看不清任何细节的小点」
promptTemplateTiny: "野外大远景实拍:手机原相机主摄不变焦,{scene}{position}有且仅有{count}{species}{sizeHint},远到看不清任何细节,只是隐约可辨的{tone}小点,画面绝大部分是{scene},没有任何靠近镜头的动物,{light},写实野外摄影,真实照片质感"
lights: [清晨柔和阳光, 正午明亮天光, 傍晚金色斜阳, 阴天柔和散射光]
# 负样本生成(技术设计.md「负样本库」):场景池按「三物种各自易被误认的形状/机理」系统穷举
# (细长轮廓→雉鸡 / 圆拱形→野兔 / 高处停息悬挂→斑鸠 + 室内/户外空镜),模板与正样本同相机词
# 同质感词、不含任何目标词;{scene} 按序循环取池(保证每个短语均匀覆盖)。
# 混淆动物单独模板——否定句只排除目标物种(图里的猫狗麻雀正是要教的"非目标")。
# 生成后自动过 RF-DETR 全图检测,有检出即剔除不入库(空检合格才进负样本库)
negativePromptTemplate: "写实摄影:手机原相机主摄不变焦,{scene},光线自然,画面中没有任何动物、飞鸟和人物,真实照片质感"
negativeScenes: [
靠墙立着的扫把和拖把, 门口的门框与墙角线, 桌角与椅腿的斜线构图, 靠墙的雨伞和登山杖,
花园里斜插的竹竿和植物支架, 生锈的铁栅栏立柱, 盘绕在地面上的花园水管, 靠墙放着的铝梯,
晾衣杆上挂着一排衣架的剪影, 斜靠在树干上的长树枝, 篮球架的立柱与篮筐, 路边的电线杆与斜拉钢缆,
路边圆圆的石头和土块, 老树桩与盘结的树根, 装满东西的麻袋编织袋, 门口系好的垃圾袋,
成排摆放的花盆与陶罐, 沙发上摞着的靠垫抱枕, 草地上的干草垛, 屋顶堆放的旧瓦片,
地上放着的双肩包, 花园角落的堆肥堆, 电线上的绝缘子和一串小灯泡, 缠挂在电线上的旧风筝,
屋檐下挂着的灯笼和玉米串, 挂满柿子的果树梢, 建筑外墙的空调外机与管线, 树枝上成簇的松果,
悬在树杈间的大草团, 路灯灯头与监控探头, 阳台上悬挂的衣物, 树杈间卡着的塑料袋,
客厅一角布艺沙发与茶几, 卧室床铺与床头柜, 厨房台面灶具与悬挂的锅铲, 卫生间瓷砖与毛巾架,
书桌电脑键盘与零散杂物, 车库里堆放的纸箱工具和靠墙的自行车, 楼道里的消防栓与管道,
阳台栏杆与洗衣盆, 餐厅餐桌餐椅与吊灯, 空旷的开阔草地, 茂密的灌丛坡地,
林地边缘的树木与草地交界, 积雪覆盖的开阔旷野, 河边大片卵石滩, 收割后的农田田埂,
茂密的芦苇丛, 城市人行道与斑马线, 露天停车场的车辆间距, 公园步道与路边长椅
]
negativeHumanPromptTemplate: "写实摄影:手机原相机主摄不变焦,{scene},光线自然,画面中没有雉鸡、野兔和斑鸠,真实照片质感"
# 人物/衣物池(2026-09-07 用户定案):人与服饰永远不会是识别目标,可安全进统一负样本;
# 动物(猫/狗/鸽子等)不进统一负样本——它们将来可能训练成正式识别目标,公共负样本会压杀自家模型。
# 此类带主体图不参与空检剔除(RF-DETR 检出人是预期,无法按物种甄别),靠提示词保证不含目标物种
negativeHumans: [
远处田间弯腰劳作的农民, 公园小路上散步的行人, 石子路上迎面走来的游客, 蹲在田埂上休息的人,
骑电动车驶过乡间道路的人, 树丛边缘经过的穿迷彩服的人, 挂在晾衣绳上的外套和花色衣物,
阳台栏杆上晾晒的被褥和衣物, 坐在长椅上穿深色外套的人的背影, 草地远处玩耍的孩童身影
]
# 目标尺寸提示(sizeHint):按「体高 × focalPx ÷ 表单距离」算出目标在图中的像素高与占比,
# 注入模板 {sizeHint}——把「厘米」换算成「米」再参与投影公式;focalPx = 图高/2 ÷ tan(vfov/2)
# 站高取数据集表 gen_heights(创建数据集时 VLM 生成,界面不维护,代码/配置不硬编码)
assumedVfovDeg: 52 # 镜头垂直视场角(度),固定为手机默认主摄(2026-08-28 用户定案;
# 曾随机 [15,90]、曾试超广角 90,均已否决)
# 训练通道(并发度 1:GPU 独占,同时仅一个 running 任务——2026-09-03 起忙时新任务落 queued 排队,
# 轮询在 running 结束后自动按创建顺序晋级启动,一次一个):
# mode=subprocess 训练机与服务器同机;mode=ssh 异机(训练脚本/数据集经 ssh 通道同步)
training:
mode: subprocess # subprocess | ssh2026-09-09 本机 M1 训练:subprocess;正式训练机切回 ssh
ssh:
# host: "192.168.3.210" # 训练机地址(mode=ssh 必填)
host: "192.168.3.210"
user: "root"
port: 22
privateKeyPath: "" # 私钥路径与 password 二选一
password: "123"
workdir: /Users/zhangbin/yolo-workdir # 训练机工作目录(train_server.py / yolov8s.pt / yolov8n.pt 所在)
venvPython: /Users/zhangbin/yolo-venv/bin/python
datasetDir: datasets # 训练机数据集根目录(相对 workdiryolo/<name> 为子目录)
timeoutMinutes: 0 # 训练超时判死(started_at 起算;0 = 不限时,2026-09-10 用户定案训练时长不受限。存活探测失败仍按进程退出判死)
# 双档位(2026-09-03 用户定案):s 档(高识别,默认)与 n 档(高性能)各自基座/分辨率;
# 一次「开始训练」按档位各建一条任务(请求 variants 可限定单档);epochs/batch/device 双档共用。
# n 档未配置(modelN/imgszN 缺一)时发起含 n 档的请求报错
model: yolov8s.pt # s 档训练基座权重(须已同步到训练机 workdir;s 容量适配小目标+遮挡,详见技术设计)
imgsz: 1280 # s 档训练/导出分辨率(须与 App 端推理输入对齐;1280 提升远距离小目标保留像素)
modelN: yolov8n.pt # n 档(高性能)训练基座权重(须已同步到训练机 workdir)
imgszN: 704 # n 档训练/导出分辨率(704² 端侧计算量约 s@1280 的 1/8,速度优先)
epochs: 150 # 训练轮数(patience 30 早停,设大可自动停)
batch: 16 # 批大小(按训练机显存调整)
device: "mps" # GPU 编号(cpu 用 cpu;M1 本机用 mps,训练机切回时改回 "0"
# RF-DETR 预标注服务(管理端标注工作台):需从服务器可达,未配置时预标注接口返回「标注服务未配置」
# 2026-09-10 本机架构:检测=local-ai(18082, rfdetr-xlarge)VLM=omlx(18081, 多模态 MLX 模型)
localAi:
baseUrl: "http://127.0.0.1:18082" # local-ai/v1/detectionLaunchAgent 自启 ~/localai/start.sh
model: rfdetr-xlarge
vlmBaseUrl: "http://127.0.0.1:18081" # omlxOpenAI 兼容 /v1/chat/completions;空则回落 baseUrl
vlmApiKey: "wenwu901" # omlx api_key~/.omlx/settings.json auth 节点)
vlmModel: Qwen3.5-9B-MLX-4bit # VLM 模型(omlx 多模态 MLX 4bit;备选 gemma-4-E4B-mlx-4bit,空闲 10 分钟自动卸载)
threshold: 0.2 # 候选置信度下限:0.2 以下直接丢弃(不入库);0.08 实测过低——COCO 通用 rfdetr 对类鸟纹理在 0.08~0.2 区间输出大量噪声候选
confConfirmed: 0.5 # 置信度 ≥ 0.5 视为确认(class 0 真目标)0.2~0.49 落疑似(class 1)待人工复核(2026-09-02 RNPHE_257 实测调定:误检可达 0.46~0.5 且与真目标仅差 ~0.1,误检落 class 0 会污染训练正样本)
overlapThreshold: 0.3 # 重叠去重阈值(交叠/较小框面积,NMS 风格;RF-DETR 同目标常输出一大一小两框,minIoU 比 IoU 更能命中)
inputSize: 700 # 提交前整图等比缩放最长边;RF-DETR 模型包固定 700x700 输入(stretch 拉伸、不支持动态尺寸,见模型包 inference_config.json),提交更大最终也拉伸到 700 无增益,2026-09-01 实测回退
# 预标注四级漏斗(技术设计.md「预标注四级漏斗」):全图扫描空检 → 切片扫描 → VLM 提议候选区精修,键见下
tileThreshold: 0.12 # 切片级候选置信度下限:小目标(切片后 ~40px)置信度天然偏低,量级取 RF-DETR-S 实测经验;低于全图 threshold 的候选仍入库落疑似(class 1)待人工复核,宁多勿漏
tileSize: 1024 # 切片块长边(原图像素):缩至 inputSize 后约 0.68 倍,画面高 2% 的目标(~64px)保住 ~44px 可检,全图直缩只剩 ~15px;块过小则滑窗块数爆炸,1024 为精度/块数平衡
tileOverlap: 0.25 # 相邻块重叠比:跨块目标不因切缝丢失;跨块重复检出由 overlapThresholdminIoU)去重
# 标注类别名(写入 data.yaml,随 result.json 存模型 labels)从数据集表取:
# 第一类 = gen_species(空回退数据集名),第二类 = gen_classes(空回退 class0/class1
labelTask:
# 预标注并发度(逐张调 RF-DETR,缺失或非法时回退默认值)
poolSize: 4
annotateReward:
# 标注众包时长激励(技术设计.md「App 标注众包与时长激励」;缺失/非法回退 consts 默认值)
claimSize: 10 # 每次领取图片数
claimTimeoutHour: 2 # 领取锁超时(pending 超时未提交视为放弃,领取时惰性释放)
rewardPerImages: 10 # 每累计提交 N 张发一次时长
rewardMinutes: 30 # 每次发放分钟数(license 到期时间分钟级顺延)
dailyCapMinutes: 120 # 每日发放上限(自然日)
freezeRatio: 0.8 # 通过比例(approved/(approved+rejected))低于该值触发冻结
freezeMinReviewed: 5 # 触发冻结判定的最小已审核样本数(防小样本误冻)
freezeHours: 24 # 冻结时长(license.annotate_frozen_until 时间戳对比自动解冻,基线重置后统计重新累计)
# 套餐定价(静态配置,改价 = 改本节点后重启服务;金额单位为分,展示名由 days 派生"N天"
plans:
- id: day
days: 1
price_cents: 1000
- id: week
days: 7
price_cents: 5600
- id: month
days: 30
price_cents: 18000
payment:
# 回调验签/IO 处理并发度(缺失或非法时回退默认值)
poolSize: 16
wechat:
# 微信支付 APP 支付(APIv3),商户号未配置时接口返回「支付未配置」
appid: "" # 开放平台 AppID
mchid: "" # 商户号
apiV3Key: "" # APIv3 密钥
serialNo: "" # 商户证书序列号
privateKey: "" # 商户 API 私钥文件路径(PEM)
notifyUrl: "" # 回调地址,如 https://animal-spot.icu/api/v1/payment/wechat/notify
alipay:
# 支付宝 APP 支付,未配置时接口返回「支付未配置」
appid: "" # 开放平台 AppID
privateKey: "" # 应用私钥文件路径(PEM)
alipayPublicKey: "" # 支付宝公钥文件路径(PEM)
sellerId: "" # 收款方 PID(回调校验 app_id/seller_id 用)
notifyUrl: "" # 回调地址,如 https://animal-spot.icu/api/v1/payment/alipay/notify