This commit is contained in:
toom1996
2026-10-18 17:42:10 +08:00
parent 1b06bd5bda
commit 1de1ec46a6
58 changed files with 5281 additions and 19191 deletions

View File

@ -28,6 +28,8 @@ type Config struct {
Ingest IngestConfig `yaml:"ingest"`
// S4 缤纷云对象存储配置(S3 兼容,爬虫入库图片上传目标)。
S4 S4Config `yaml:"s4"`
// Vision 视觉服务(FashionSigLIP)配置,用于「疑似同款」提示。
Vision VisionConfig `yaml:"vision"`
// loadedFrom 记录实际生效的配置文件绝对路径,仅用于启动日志。
// 小写不导出,yml 无法覆盖它。
@ -154,6 +156,36 @@ type S4Config struct {
StyleThumb string `yaml:"style_thumb"`
}
// VisionConfig 视觉服务(FashionSigLIP)配置。
//
// 入库时把每张图编码成 768 维归一化向量写入 image_embeddings(HNSW 余弦索引),
// 后台图集页据此提示「疑似同款」。服务不可用时自动降级为「不产出向量」,绝不阻断入库。
//
// 维度 768 为 M0 spike 实测值(模型 Marqo/marqo-fashionSigLIP 输出 768 维,非 512)。
// 生产部署无 GPU,CPU 推理;本地开发可用项目 .venv(CUDA torch),两者算出的向量数值一致。
type VisionConfig struct {
// Enabled 总开关;关闭则完全跳过 embed 调用。env: VISION_ENABLED
Enabled bool `yaml:"enabled"`
// Endpoint 服务地址,仅监听内网。env: VISION_ENDPOINT
Endpoint string `yaml:"endpoint"`
// TimeoutSeconds 单批 embed 超时(秒),默认 5。env: VISION_TIMEOUT
TimeoutSeconds int `yaml:"timeout_seconds"`
// Dim 向量维度,必须与模型一致;M0 实测为 768。env: VISION_DIM
Dim int `yaml:"dim"`
// SimilarThreshold 「疑似同款」余弦相似度阈值,由真实 runway 数据实测校准。
// env: VISION_SIMILAR_THRESHOLD
//
// 默认 0.93。实测依据(已排除同图集,只比跨图集):
// - 「不同图」的跨图集最佳相似度:min 0.676 / 中位 0.781 / 上限约 0.90
// (同品牌各季同风格,语义相似度天然偏高)
// - 「同一张照片」的跨图集重复:整齐落在 1.0000
// 0.93 取在噪音上限与真重复之间的空隙里。参照:0.68 时实测 100% 的图都会挂提示
// (纯噪音);而 0.85 已能滤掉绝大多数噪音。
SimilarThreshold float64 `yaml:"similar_threshold"`
// FailThreshold 连续失败多少次后熔断冷却(5 分钟)。env: VISION_FAIL_THRESHOLD
FailThreshold int `yaml:"fail_threshold"`
}
// ClientSignConfig 公开接口「前端 JS 签名」配置。
//
// 给 /runway-looks(列表)与 /brands 两个批量查询接口加一层请求签名校验,
@ -230,8 +262,8 @@ func defaultConfig() *Config {
Burst: 40,
},
Ingest: IngestConfig{
Secret: "",
TTLSeconds: 300,
Secret: "",
TTLSeconds: 300,
DownloadProxy: "",
},
S4: S4Config{
@ -378,6 +410,14 @@ func (c *Config) applyEnv() {
envStrFirst(&c.S4.BaseURL, "S4_BASE_URL", "QINIU_BASE_URL")
envStrFirst(&c.S4.StyleDisplay, "S4_STYLE_DISPLAY", "QINIU_STYLE_NORMAL")
envStr("S4_STYLE_THUMB", &c.S4.StyleThumb)
// 视觉服务(FashionSigLIP):入库时产出「疑似同款」用的语义向量。
envBool("VISION_ENABLED", &c.Vision.Enabled)
envStr("VISION_ENDPOINT", &c.Vision.Endpoint)
envInt("VISION_TIMEOUT", &c.Vision.TimeoutSeconds)
envInt("VISION_DIM", &c.Vision.Dim)
envFloat("VISION_SIMILAR_THRESHOLD", &c.Vision.SimilarThreshold)
envInt("VISION_FAIL_THRESHOLD", &c.Vision.FailThreshold)
}
// normalize 兜底与校验:修正非法值,避免运行期出现难以定位的问题。
@ -432,6 +472,23 @@ func (c *Config) normalize() {
if len(c.CORS.AllowOrigins) == 0 {
c.CORS.AllowOrigins = []string{"*"}
}
// 视觉服务(FashionSigLIP)默认值:留空时兜底为本地服务与实测维度。
if c.Vision.Endpoint == "" {
c.Vision.Endpoint = "http://127.0.0.1:8900"
}
if c.Vision.TimeoutSeconds <= 0 {
c.Vision.TimeoutSeconds = 5
}
if c.Vision.Dim <= 0 {
c.Vision.Dim = 768
}
if c.Vision.FailThreshold <= 0 {
c.Vision.FailThreshold = 3
}
if c.Vision.SimilarThreshold <= 0 {
// 0.93 为实测校准值:跨图集「不同图」上限约 0.90,真重复落在 1.0000,取空隙中点。
c.Vision.SimilarThreshold = 0.93
}
}
func envStr(key string, dst *string) {
@ -473,3 +530,11 @@ func envBool(key string, dst *bool) {
*dst = v == "1" || v == "true" || v == "yes"
}
}
func envFloat(key string, dst *float64) {
if v := strings.TrimSpace(os.Getenv(key)); v != "" {
if f, err := strconv.ParseFloat(v, 64); err == nil {
*dst = f
}
}
}