news 2026/9/18 20:29:26

CivitAI 付费模型加载(Paid Model Loading)实施全解:阶段式清单、覆盖率变更与编排器集成

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CivitAI 付费模型加载(Paid Model Loading)实施全解:阶段式清单、覆盖率变更与编排器集成

CivitAI 付费模型加载(Paid Model Loading)实施全解:阶段式清单、覆盖率变更与编排器集成

【免费下载链接】civitaiA repository of models, textual inversions, and more项目地址: https://gitcode.com/GitHub_Trending/ci/civitai

导读

本文围绕 CivitAI 仓库中 docs/features/paid-model-loading-checklist.md 这一实施清单,系统拆解"付费模型加载"(Paid Model Loading)从决策、服务端管道、审核测试页、覆盖率变更到公开界面与编排器状态验证的完整落地过程。读完本文,你将掌握:该功能如何让"任意检查点"通过付费加载进入生成集群并承诺 48 小时驻留、GenerationCoverageNext覆盖率模型如何替换旧的CoveredCheckpoint门控、购买路径(estimate/submit)与分级限流的实现细节,以及@civitai/clientSDK 背后编排器(orchestrator)真实能力与文档中"未构建"差距的核对方法。

功能背景:付费模型加载是什么

付费模型加载的核心设想是:站点上任何模型都变得可生成。若模型未驻留在生成集群中,用户付费将其加载进来,并——按最初承诺——保证其驻留48 小时。价格由编排器按模型大小缩放设定(详见 docs/features/paid-model-loading.md)。

要点:

  • 驻留机制真实存在(Koen 2026-09-04 确认):spine 控制器在驱逐资源前会互相检查,除非另一个 spine 控制器持有副本,否则拒绝驱逐任何不足 48 小时驻留的资源PrepareResourceJob负责把资源下载进数据中心,其后由该驱逐策略守护其生命周期(代码位于civitai-spine-controller仓库的ClusterAwareEvictionPolicy.cs)。文档曾误以为PinModelJob是目标原语,实际它是遗留物
  • "除非另一个控制器持有"是良性的:它只意味着副本可能在不同 spine 控制器间迁移,可用性不中断,因此界面可以按原承诺宣传 48 小时。
  • 价格半边仍然缺失:成本函数硬编码返回零,尚无按大小缩放的价格可展示——这是 C2 任务。
  • 该功能取代拍卖(auctions)作为让检查点进入生成器的机制
  • 三个界面共享同一状态机:模型版本页、生成器、以及链接到完整队列页的导航栏指示器。

Phase 0:决策——已全部关闭(2026-09-08)

清单中 Phase 0 的每一项决策都有了答案,不再阻塞任何工作,答案与给出者记录在 docs/features/paid-model-loading-decisions.md 的 §1–§2,由决策推导出的覆盖率模型及生产审计见 docs/features/paid-model-loading-coverage.md。

决策项结论
C14 — demo client、仅审核者还是平台从已有的审核测试页(Phase 1.5)开始
"我们能诚实卖什么"按最初承诺的 48 小时;副本可在窗口内于 spine 控制器间迁移,可用性不中断
"任意模型"仅检查点——体积正是加载器存在的原因,LoRA 没有这个需求;CoveredCheckpoint停止门控生成,EcosystemCheckpointsGenerationBaseModel保留。文档中早期"LoRA 优先"的建议是错的,已删除
RentCivit许可的模型拒绝。实现为"拒绝任何不在GenerationCoverage中的内容"——今天零个已覆盖版本缺少该许可,且以继承规则的方式而非重述规则

不阻塞站点工作、但阻塞上线的项:

  • C2 — 按模型大小定价并启用收费(Koen 负责)。已核实:这不是开关——PrepareResourceHandler.CalculateCost返回硬编码零,因此定价函数必须新写;在此之前whatif返回 0,CTA 按钮上没有数字。
  • C3 — Koen 的交接文档:已完成并验证。
  • C13 — 驱逐指标:已完成并验证。

Phase 1:管道(Plumbing)——无用户可见界面

Phase 1 没有用户可见表面,但 Phase 2、3 的一切都建立在其上,并且可以独立针对真实下载进行测试。

C4 Webhook:以"暂不"关闭

C4 — 编排器在下载开始/推进时命中的端点,以"暂不"关闭(见 决策 2.4)。其存在的两个理由都消失了:C9 属于 Phase 2,且旁观者需要的是"完成时通知"而非实时进度。Phase 2 需要服务端发送时机时会重新打开。

主题广播助手与信号消息

  • sendSignalToTopic(topic, message, data)位于 src/server/orchestrator/orchestrator.utils.ts,用withSignals()包裹。⚠️ 目前仍无调用方,也没有计划中的调用方——加载进度改为按用户投递且 C4 已关闭;它留待 Phase 2 需要时使用,若 Phase 2 不需要则应删除。源码中该函数实际 POST 到${SIGNALS_ENDPOINT}/groups/{topic}/signals/{message},与聊天所用形状一致。
  • 新增SignalMessages条目ResourceLoadUpdate = 'resource-load:update',投递到用户自己的频道而非主题。与已有的SchedulerDownload = 'scheduler:download'(那是生成历史导出,不是本功能)不冲突。

提取 versionId → AIR

modelVersionToAir位于 src/server/utils/resource-air.ts;bustOrchestratorModelCachemodelVersionResourceCache均改指向它。fileType仅在调用方已加载文件时来自主文件——源码注释明确指出:传了files与没传files的调用方,是在询问两个不同的 AIR(检查点主文件若是 diffusion model/UNet 会改变所广告的种类)。

服务端资源状态读取

  • getResourceLoadState(versionIds)getResourceLoadQueue({cursor, take})位于 src/server/services/resource-load.service.ts,通过resourceLoad.getState/resourceLoad.getQueue暴露(两者均为publicProcedure,C5 之前保持旗标门控)。队列读取经由新加的queryResourcesClient包装器(位于services/orchestrator/models.ts,SDK 调用保持在服务层)。
    • 新鲜、未缓存——不复用modelVersionResourceCache(其日级 TTL 且丢弃availability);
    • 本构建不认识的状态上报为unknown,不折叠进四种已知状态之一。

服务测试

src/server/services/tests/resource-load.service.test.ts 覆盖:AIR 构造、unavailable上的queuePositionunknown回退、无法解析的队列行、四种预提交拒绝(不可生成、无权重文件、未扫描文件、版本不存在)、进度 URL 指向/users/而绝不指向/groups/、owner 检查传播、有价与无价。尚未钉住的是unsupported与已available的拒绝。测试还演示了unknown语义:编排器返回{ status: 'evicting', someNewField: 1 }这类未知状态或完全无数据时,均上报unknown

购买路径

resourceLoad.estimate(whatIf)与resourceLoad.submit已存在、已门控、可工作;缺的只是可展示的价格。

  • assertWorkflowOwner用于 submit 结果——源码中submitResourceLoadsubmitWorkflow后立即调用assertWorkflowOwner(workflow, userId, token),受no-unguarded-billable-submit守卫约束(该守卫的 docstring 点名的故障模式正是"新付费功能自建submitWorkflow调用,而该 diff 的评审者没有理由把它与另一子系统的账单事故联系起来")。
  • status === 'unsupported'以及完全读不到状态时拒绝。
  • ✅ 已available不扣费拒绝——resolveLoadable中的注释解释:编排器接受已驻留的 prepare 并瞬间完成,用户会白付钱。
  • ✅ 价格来自whatIf提交而非站点侧价格表——estimateResourceLoad返回{ cost, priced },编排器报价为零时priced为 false,任何界面都无法把"免费"渲染成报价。仍被 C2 阻塞。
  • ⬜ 干净地呈现编排器自身的CanGenerate拒绝——PrepareResourceInput会在任何扣费前抛出ValidationException
  • ✅ 模型缺少RentCivit许可时拒绝——实现为resolveLoadable!eligible拒绝:覆盖率(GenerationCoverageNext)与生态类型支持由isGenerationEligible组合,estimatesubmit都走它。

resolveLoadable的完整拒绝链(源码):

  1. !state.eligible→ "此资源无法在站点上生成,加载它买不到任何东西";
  2. !state.loadable→ 按UNLOADABLE_MESSAGESno-weights/unsupported-format两种文案)拒绝;
  3. unsupported→ "生成集群无法托管此资源";
  4. unknown→ "无法读取资源状态,请重试";
  5. available→ "资源已加载,可直接生成"。

C10 — 分级每日速率限制

档位每日加载数
Free0 —— 在到达限流器前即被assertCanRequestLoad拒绝
Bronze3
Silver6
Gold / Founder10

每日阶梯之上还有一条与档位无关的 3 次/小时扁平限制——这是对集群的突发保护,不是权益,任何套餐都不能豁免。机制是现有rateLimit()tRPC 中间件(src/server/middleware.trpc.ts)。清单与源码(src/server/routers/resource-load.router.ts)记录了六条决定上限是否真正成立的性质:

  1. 分级阶梯可正确组合:每周期最高匹配上限生效,金卡用户同时命中无条件和金卡两行时得到 10 而非 0;
  2. limit: 0不是成员门槛:它可干净短路,但中间件对审核者及 dev/test/preview 环境提前返回,预览构建上再无其他东西拦住免费账号的免费加载——assertCanRequestLoad()才是门槛。userTiers['free', 'founder', 'bronze', 'silver', 'gold'],若免费行写成userReq: (u) => u.tier === 'free'而非无条件行,任何未匹配档位都等于没有限制validLimits为空、检查循环不执行、canProceed保持 true),因此免费行必须是无条件兜底且founder需要自己的行;
  3. 差一错误:比较是attempts > limit,因此每个非零数字都多放行一次——3 意味着 4。要么接受并写下来,要么改中间件(但它是全应用共享的,改它会波及所有限流器);
  4. 审核者完全跳过限流(dev/test/preview 同),所以仅审核者上线等于没有任何上限,也无法验证上限是否有效;
  5. 失败开放:Redis 写入降级时请求被放行且少计(rate-limit-write-degraded)。对配额可接受,但要知道它不是硬上限;
  6. 使用onlyCountSuccess: true:被拒绝的购买(不支持的资源、已驻留、Buzz 不足)不应烧掉金卡用户的每日额度。resourceLoadRateLimits数组(src/server/routers/resource-load.router.ts)展示了完整配置:每日行是权益(套餐包含什么),每小时行是集群的(扁平、无套餐可豁免),两者在同一个sharedKey: 'resource-load:submit'上组合。

🔴同一sharedKey必须应用到生成提交路径,否则通过 txt2img 隐式触发的 prepare 会完全绕过上限——当前上限对"直接生成而非按按钮"的人只是装饰。

Phase 1.5:审核测试页

构建计划之外的产物,是为了在 Phase 2 存在之前就能端到端驱动管道。

  • /moderator/resource-load——requireModeratorresourceLoad旗标:
    • 提交模型版本 id,在提交前解析出:名称、AIR、大小、可用性、是否可生成/有权重;
    • 估算按钮在原因已知时禁用并显示原因,而不是提交时才失败;
    • 编排器报价为零时,估算自称"未定价";
    • 来自持久化 store 的"等待中"列表,带实时进度与"停止关注";
    • 集群队列每 15 秒轮询,有实时信号进度时优先采用;
    • 通过买家自己的信号频道接收实时进度;
    • ⚠️ 审核者豁免rateLimit(),此页完全不检验 C10。
  • 跟踪与通知—— src/store/resource-load.store.ts(持久化、自排空、48 小时上限)与ResourceLoadDrain挂载在AppHeader,任何带resourceLoad旗标的已登录用户都会在下次落地页面时收到已完成加载的报告(toast 需手动关闭)。
  • 此页之外还没有任何入口能创建关注:store 支持kind: 'watching'且 drain 会报告它,但创建它的按钮是模型版本页上的 C5 任务——旁观者通知已构建但不可达。

客户端 store 的排空语义(源码级)

resourceLoadDrainVerdict(纯函数,可在无浏览器环境下测试)在每次页面加载时对每个条目判定:available完成(toast 后移除);版本缺失移除;loading或带位置的在队列中保留;其余移除(无在途加载)。"每一条目都必须能离开"是关键:失败的加载与完成后被驱逐的加载都会读回unavailable,与"排队中"无法区分,因此RESOURCE_LOAD_EXPIRY_MS = 48h是必须的——它匹配驻留策略;但上限不得吞掉好结果——加载在上限之后完成仍要报告。track重新跟踪时保留原始requestedAt,防止每次访问刷新让条目活过自己的截止时间。

Phase 1.6:覆盖率变更

由 Phase 0 在 2026-09-08 的答案产生。规则、审计与每个测量数字都在 docs/features/paid-model-loading-coverage.md。

新的覆盖率视图GenerationCoverageNext

  • GenerationCoverage并排的新视图:迁移 packages/civitai-db-schema/prisma/migrations/20260908120000_generation_coverage_next/migration.sql 创建GenerationCoverageNext2026-09-08 已应用到生产。🔴 不命名为GenerationCoverage2:该名字在生产中已作为早期过期实验存在,CREATE OR REPLACE会静默覆盖它。刻意不加入schema.full.prisma——切换时用新视图体替换GenerationCoverage自身并删除该视图,Prisma 模型永不变。三分支:无加载文件(已覆盖、永不被加载)、在EcosystemCheckpoints中且有加载文件、以及GenerationBaseModel基模型上的检查点且有加载文件。LORA/TI/VAE/LoCon/DoRA/Upscaler 分支不变。
  • ✅ 去掉CoveredCheckpoint合取项,允许Diffusers但保持 Core ML 与 ONNX 排除(数字见覆盖率文档)。
  • 检查点必须有 SafeTensor 权重文件:迁移20260909180000_generation_coverage_next_safetensor_checkpoints(2026-09-09)收窄了 09-08 的视图:Diffusers 对除检查点外的所有类型仍可加载,CoveredCheckpoint以析取项回归、豁免 6 个驻留拍卖的版本。已编写、尚未应用到任何环境。
  • ⬜ 🔴 保留EcosystemCheckpoints—— 63 个检查点默认值中有 62 个依赖它。
  • ✅ 与生产对比(2026-09-08)——当时无任何覆盖损失。
  • ⬜ 🔴应用 SafeTensor 迁移后 2,242 个已覆盖检查点失去覆盖(33,811 → 31,569;其中 834 个有生成历史,6.5M 生命周期生成量)。这是收窄,没有安全窗口——应在covered的读者就绪时再应用。关闭条件:应用到生产且已覆盖检查点计数读数为 31,569。

覆盖率数字(2026-09-08 同一查询测出)

GenerationCoverageGenerationCoverageNext
已覆盖检查点63833,796
全部类型已覆盖行899,553933,386

+33,158 检查点、+33,833 行。两者增量不同是因为从排除格式中移除Diffusers惠及所有类型而非仅检查点——约 675 行新增为 LoRA 等。⚠️514 不是已覆盖检查点数,它是CoveredCheckpoint(拍卖名单)的行数;今天有 638 个版本以检查点身份被覆盖,因为EcosystemCheckpoints也贡献。加载器群体分桶:EcosystemCheckpoints125 个(A 类 51 个无加载文件 → 永不加载,B 类 74 个走加载器),社区检查点 33,792 个(A 类 123,B 类 33,669)——约33,743 个可加载检查点,对比拍卖今天覆盖的 514 个。

许可门禁

零个已覆盖版本缺少RentCivit,两种方式验证(逐分支 + 端到端对视图:899,068 已覆盖行、0 无许可)。视图有两条不检查许可的分支——EcosystemCheckpoints成员与usageControl = 'ExternalGeneration'——但当前无任何版本借此逃逸(这两分支覆盖的 143 个版本都持RentCivit)。结论:门禁基于覆盖而非直接测许可,因为若某版本日后走旁路它仍保持正确,且以继承规则取代第二份意见。

单一canGenerate派生

isGenerationEligible位于 packages/civitai-shared/src/generation-eligibility.ts:covered && !isGenerationDisabled(flags) && isBaseModelGenerationSupported(baseModel, modelType)。四个调用点全部改指它,no-divergent-can-generate-derivation守卫把isBaseModelGenerationSupported挡在src/之外。仅覆盖会多报 736 个版本(33 个 (baseModel, type) 组合,如 Wan Video + LORA 337、Flux.1 D + DoRA 102 等)——见覆盖率文档。

其他 Phase 1.6 条目

  • 加载 CTA 门控于isGenerationEligible且"有可加载文件"——不基于covered、不基于usageControl、不基于"有任何文件"。审核页已做,服务端在resolveLoadable中强制;C5/C6 添加公开 CTA 时复查。
  • estimatesubmit拒绝任何不在覆盖中的内容(即RentCivit门)——resolveLoadable读取GenerationCoverageNext
  • 审计covered的每个现有读者:23 个文件,分类见覆盖率文档。分类 A(生成门禁,generation.servicecanGenerateresource-data.redis.ts)在调度切换前必须精读;B 搜索(models.search-index.ts 与 models-update.ts);C 展示(各 controller/selector 与/api/v1/model-versions/mini/[id]——后者已切换,因为编排器读它做CanGenerate,实测版本 3040959 上旧视图会拒绝所有值得做的加载);D 池与相邻消费者(daily-challenge、App Blocks workflow.service、model.service.tscaches.ts的模型列表过滤);E 无操作(getCheckpointGenerationCoverage零调用方死代码,backfill-trained-model-permissions.ts的断言在新视图下仍真)。
  • ⬜ 🔴共享限流键与 C2 定价必须先于站点生成门读取新视图落地generation.serviceresource-data.redis、搜索索引。放宽它们会让数万更多版本可生成,而针对非驻留版本的生成提交会触发隐式 prepare——今天免费且无上限,因为 C10 只守resourceLoad.submit。两个已读取GenerationCoverageNext的调用方刻意在此规则之外:resource-load.service(购买路径——旗标门控,放宽正是其目的)与/api/v1/model-versions/mini/[id](编排器CanGenerate读取;无站点代码调用它)。
  • 决定搜索展示什么:索引从covered派生canGenerate,切换后会宣传数万更多模型可生成,却无法表达"需要先加载"。
  • 检查公开 API 字段/api/v1/model-versions/mini/[id]现从GenerationCoverageNext选择covered(2026-09-08 完成)。⚠️ 该字段对第三方消费者的含义已改变,未打旗标、未公告。
  • 查看池消费者——每日挑战模型选择、App Blocks 工作流服务、model.service.tscaches.ts的模型列表过滤。
  • 删除getCheckpointGenerationCoverage(与CoveredCheckpoint一起,零调用方)。
  • 决定handle-auctions.ts的去留(一旦无行被读取)。

36 个贴错标签的 API 模型

36 个EcosystemCheckpoints版本是外部 API 模型,其唯一文件是Training Data格式Other。决策(Justin 2026-09-08):将其usageControl设为ExternalGenerationmodel-version.controller.ts拒绝非审核者设置该值,因此是直接 DB 写或审核者操作。已验证安全:ExternalGeneration视图分支要求已发布且非 POI,36/36 均满足,覆盖保持不变。

Phase 2:公开界面(依赖 C14 决策)

  • C5 — 模型版本页:Create 按钮下方;对所有人可见而非仅购买者;四种状态(unsupported完全无 CTA);订阅按钮让旁观者可采纳他人进行中的加载;页面已订阅model-version:<id>——扩展而非新增第二个订阅。
  • C6 — 生成器:未加载 → 按大小定价提供付费加载;下载中 → 自动订阅并对所选资源内联显示进度;已加载 → 不变;"任意模型"决策已定(仅检查点)。C6 现在依赖Phase 1.6落地而非决策。
  • C7 — 导航栏指示器:镜像 src/components/Resource/UploadTracker.tsx——同样的Indicator+Popover形状,挂在AppHeader其旁;先显示队列位置,下载开始后显示进度,按钮通向队列页;localStoragestore,挂载时轮询资源端点、丢弃已完成项、对其余重新订阅;⚠️ popover 在 header 内,需显式传withinPortal(应用主题将Popover设为withinPortal: false,否则会被裁剪)。
  • C8 — 队列页:读取resourceLoad.getQueue(服务端包装queryResources({ view: 'queue' })),轮询;信号订阅仅限本用户等待的条目;跨 provider 排名已在服务端完成,不要重建;⚠️ 游标是活重排列表上的整数偏移,分页不稳定——保持take小(每项服务端要两次 grain 调用)。
  • C9 — 加载完成通知:发给购买者每个在 C5 按过订阅的人;需要NotificationCategory与设置条目——notification-settings-polarity守卫(src/server/notifications/tests/)钉住默认极性。

Phase 3:后果

  • 盯住驱逐指标:C13 已暴露它,但无人查看。首次公开加载前把它放上仪表盘——它是 Briant"饥饿"担忧的唯一仪器。关闭条件:指标在某个有名者监看的仪表盘上。
  • C11 — 退役拍卖:在 868gtq1kt(把 featured 从拍卖中拆出)有答案前不划定范围——拍卖承担两个职责,付费加载替换其一。约 89 个src/下文件涉及。CoveredCheckpoint冲突已通过将其从覆盖合取项移除(Phase 1.6)解决——拍卖任务不能再"取消覆盖"付费检查点;它作为析取项存活、覆盖 6 个缺 SafeTensor 文件的驻留拍卖版本(这些都不加载,故不可能被付费过)。剩余问题只是该任务是否继续写无人读取的行。

编排器状态:对照源码验证

以下信息直接读自编排器仓库(civitai-orchestrationmainat9306e7333)而非 SDK。该提交已部署,因此下面标记为"已构建"的一切都已上线。

已构建并可工作

事项状态
GET /v2/resources?view=queue已实现ResourcesController.QueryAsync):合并每个启用 provider 的队列、按 AIR 去重、排名、分页。一个不可达 provider 降级为空贡献而非让调用失败。"把各 provider 排名拍平成 1..n"已在服务端完成,客户端勿重建
GET /v2/resources/{air}已实现:在控制器层把availability拼接到ResourceInfo,按资源做响应缓存
四种可用状态与 SDK 类型完全一致(ResourceAvailability.cs),含queuePosition只存在于unavailable
prepareResource作为工作流步骤存在——PrepareResourceStep含 handler、PrepareResourceJob与生命周期校验,标记[Preview];非仅 recipe,调用信号设计成立
进度事件存在step:*已能接收
已驻留时的实例成功handler 检查可用性,资源available时不发 job——重复 prepare 免费且瞬间完成

进度事件——比 SDK 暗示的更好

卡在下载上的步骤会发布WorkflowStepEvent,携带Preparation { Resource, QueuePosition, Progress, EtaSeconds }——正是 UI 需要的负载。

  • 刷新间隔10 秒PreparationRefreshInterval);注释解释为何更紧无意义:worker 本身大致以该速率上报资源成本。
  • 发布按变更去重、1% 进度粒度(PreparationProgressPublishThreshold = 0.01),完整下载最多约 100 个事件。
  • 门控规则:"进度最差的 job 门控该步骤"。

🔴step:preparing被刻意从 OpenAPI 枚举中隐藏WorkflowCallbackSchemaFilter显式从广告值中移除preparingscheduled,这就是生成 SDK 联合只列生命周期转换、让人以为功能缺失的原因。功能没缺,只是未广告。step:*订阅即可匹配包括Preparing在内的每个状态——分发测试是x.EventType is null || x.EventType == @event.StatusgetOrchestratorCallbacks已用step:*,生成今天就在接收这些事件。K2 答复:Koen 已把缺失事件类型补进规范,未来@civitai/client发布应携带类型。

未构建

🔴 此表曾有一行称 48 小时保证不存在——那是错的,且错在最昂贵的方向上:它宣称产品头条特性缺失。机制位于civitai-spine-controller——本清单从未读过的仓库;PinModelJob作为原定原语是遗留物(Koen,2026-09-04)。唯一真实差距是定价。

差距后果
🔴成本硬编码为零PrepareResourceHandler.CalculateCost返回{ Factors = [], Fixed = [] },其自身注释说两个集合都空即短路为零成本C2 不是配置开关——按大小缩放的定价函数尚未编写。?whatif=true今天返回而非价格,CTA 没有数字可显示

驻留——本清单未读的仓库

此处无法验证:civitai-spine-controller未在站点侧检出。记录的是 Koen 的答复(DM,2026-09-04)而非读到的源码:

  • spine 控制器在驱逐资源前互相检查,拒绝驱逐任何不足 48 小时驻留的资源,除非另一个 spine 控制器持有它
  • PrepareResourceJob的唯一职责是把资源送进 DC;驱逐策略自此守护其生命周期(ClusterAwareEvictionPolicy.cs);
  • PinModelJob是遗留物——"看都不用看"
  • ⚠️ 无任何东西暴露资源 48 小时窗口何时结束——仍无倒计时可构建。

值得知道的站点相关细节

  • 队列游标是整数偏移而非稳定游标:排名每请求从实时 provider 状态重算,队列变动时条目在页间移动。适合单首页;勿构建假设稳定性的分页视图。
  • take被钳制在1..500,默认 100;站点侧 schema(src/server/schema/resource-load.schema.ts)进一步限制为 1..100、默认 50。
  • 队列调用对每项fan-outGetInfoAsync+GetAvailabilityAsync——500 项一页就是 1,000 次 grain 调用。保持小页、温和轮询。
  • PrepareResourceInput.OnInitializedAsync拒绝CanGenerate为 false 的资源,抛ValidationException——这是编排器自己的覆盖门,会在我们扣费前拒绝;值得作为干净错误呈现而非 400。
  • PrepareResourceJob24 小时MaxTimeout与 2 分钟 claim 时长。以实测约 10 KB/s 带宽,大型检查点可能触及该上限。
  • GET /v2/resources需要Consumer角色;DELETE需要Manager。站点的缓存击穿路径已用系统 token 做删除。
  • 回调url是任意字符串,指向 signalsgroup/groups/model-version:{id}/signals/{message})是站点侧选择,编排器无需任何东西——这就是旁观者订阅可在无 C4 端点的情况下工作的方式。但加载进度不是主题广播:它去/users/{userId}/signals/,因为编排器直发事件体、该体指名付费用户(workflowId<userId>-<timestamp>);测试断言 URL 含/users/且不含/groups/

信号路径与通知形态

信号路径与图像生成同构:工作流 → 站点端点 → 信号服务 → 客户端。发送侧:按用户发送与主题广播都在 src/server/orchestrator/orchestrator.utils.ts;全部经 withSignals() 路由——未包裹的信号服务 fetch 正是 2026-05-30 事件循环级联事故的形态。订阅侧:useSignalTopic(topic)(src/components/Signals/SignalsProvider.tsx 的useSignalTopic)按主题引用计数、自动 join/leave 组;src/components/Model/ModelVersions/model-version.utils.ts 已订阅model-version:<id>,因此站点可按模型版本 id 订阅下载而无需新工作流步骤。主题命名约定已存在:SignalTopic.ModelVersion = 'model-version'(src/server/common/enums.ts)。

决策 1.4 纠正了早期设计:加载回调曾指向model-version:<id>信号,让所有观看该模型的人收到进度。那会泄露信息:编排器直发WorkflowStepEventworkflowId<userId>-<timestamp>——组播会把"谁付了款"告诉每个观看者。回调现指向/users/{userId}/signals/,旁观者得不到实时进度,改为在就绪时被通知。

不在 v1 范围内(记录在案)

  • 付费提升队列位置——若机器人军团击穿限流,Justin 预期它会回归。
  • 搜索结果中的加载状态。
  • 模型何时可用的硬性保证——当时数据中心带宽约 10 KB/s,LoRA 花了四小时。对到达时间不做承诺——这与到达后停留多久是不同问题(决策 1.3)。

无主缺口

真实工作但无任务、无负责人,列出以便"被决策"而非"被发现":

  • 退款路径:失败或永不完成的加载。已决策退款(决策 1.2);未决的是退——K3 问 Koen 编排器是否已做。PrepareResourceJob24 小时MaxTimeout加约 10 KB/s 带宽,使这不是罕见路径。
  • 驻留显示:驻留真实存在,但无 API 报告资源 48 小时窗口何时结束,没有可倒计时的东西。需要先向编排器提需求。

构建顺序与已决策事项(速查)

构建计划(docs/features/paid-model-loading-build-plan.md)给出四阶段顺序:Phase A(管道,已构建:resource-air.ts、schema、service、router、信号消息、回调构建器、resourceLoad旗标、/moderator/resource-load审核页)→Phase B(只读界面:store、utils、ResourceLoadCard非购买态、ResourceLoadTracker、队列页——无购买路径,故不依赖定价)→Phase C(购买:服务端半成品已构建,缺口是 CTA、干净呈现CanGenerate拒绝、以及 C2 定价)→Phase D(C9 通知、C11 拍卖退役)。"不构建"清单同样明确:不建队列排名算法、不建尺寸→价格表、不建驻留倒计时、搜索不加加载状态、v1 不做队列位置提升。

已决策、勿重开(摘要):限流在站点侧而非编排器侧;浏览器用localStorage保存"正在关注"并在每次页面加载排空(48 小时过期保证每项都能离开);购买的持久记录是编排器的工作流(标签resource-load、用买家 token 查询),不是 localStorage 也不是 Redis;进度信号去买家自己的频道;旁观者无实时进度,下次访问时被告知就绪;真正 API 级通知是 Phase 2 目标;进度显示在三处(导航栏、模型版本页 Create 下方、生成器所选资源);旁观者可订阅他人进行中的加载;加载状态与队列是公开读取;界面按原样承诺 48 小时;加载只针对检查点CoveredCheckpoint停止门控生成;只有GenerationBaseModel中的基模型可加载;检查点需SafeTensor权重文件(2026-09-09),无文件 API 模型永不加载,GGUF/PickleTensor/Diffusers 检查点得到不同拒绝文案——UNLOADABLE_MESSAGES在 src/server/schema/resource-load.schema.ts 是两者的单一来源;永不完成的加载退款;购买路径拒绝任何不在GenerationCoverageNext中的内容(由isGenerationEligible组合生态类型支持);每日上限必须覆盖隐式路径(对非驻留资源的生成提交)——同一配额而非第二配额;免费档上线即 0/天;并发 prepare 同一资源无需特殊处理。

阻塞依赖:C2(定价与启用收费)阻塞所有公开暴露——加载当前在编排器侧免费,C2 前上线站点界面等于送出集群驻留。C14(demo 客户端决策)门控 C5–C8——Briant 主张先向高级用户演示,Justin 主张小型独立第一方应用端到端驱动 Koen 的 API 或仅审核者上线;Justin 拥有该决策。

【免费下载链接】civitaiA repository of models, textual inversions, and more项目地址: https://gitcode.com/GitHub_Trending/ci/civitai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 20:23:40

计算机组成原理期末复习:知识靶向图与硬件思维训练

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/18 20:22:56

分布式置换流水车间调度实战指南:建模、算法与部署

简介&#xff1a;分布式置换流水车间调度&#xff08;DPFSP&#xff09;是智能制造与生产管理中的重要研究课题。这份PDF是一篇系统化的研究概述&#xff0c;适合工业工程、运筹优化及计算机应用方向的研究者与高年级学生阅读。内容从置换流水车间调度&#xff08;PFSP&#xf…

作者头像 李华