feat(AI): MNN 模型纳入下载体系 ModelKind.mnnLLM(Phase 4)
文本 MNN 模型用 taobao-mnn/Qwen3.5-2B-MNN 官方预转换格式(~1.10GiB), 不再从头转换(避开多模态转文本风险,官方转更可靠)。 - ModelStore.ModelKind 新增 .mnnLLM = "Qwen3.5-2B-MNN" - ModelManifest:.mnnLLM 文件清单(config.json/llm_config.json/llm.mnn/ llm.mnn.weight 1.1GB/tokenizer.txt/visual.mnn,HF API 实测字节) - AIRuntime:mnnModelFolder + 就绪判定改走 ModelStore.isComplete(.mnnLLM) - ModelManagementView:subtitle 加 .mnnLLM 文案(仅此一处,未动其它 WIP) - ModelManifestTests:+4 条 mnnLLM 断言(文件数/总字节/必需文件/URL) 模拟器 ModelManifestTests TEST SUCCEEDED。下载经现有链路,需上传到 file.myv0.com/Qwen3.5-2B-MNN/(CDN 清单随附)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,28 @@ struct ModelManifestTests {
|
||||
#expect(ModelManifest.totalBytes(for: .vl) == 3_109_729_929)
|
||||
}
|
||||
|
||||
@Test func mnnHasSixFunctionalFiles() {
|
||||
#expect(ModelManifest.files(for: .mnnLLM).count == 6)
|
||||
}
|
||||
|
||||
@Test func mnnTotalBytesMatchesManifest() {
|
||||
#expect(ModelManifest.totalBytes(for: .mnnLLM) == 1_185_759_005)
|
||||
}
|
||||
|
||||
@Test func mnnHasEssentialRuntimeFiles() {
|
||||
let names = ModelManifest.files(for: .mnnLLM).map(\.path)
|
||||
#expect(names.contains("config.json"))
|
||||
#expect(names.contains("llm.mnn"))
|
||||
#expect(names.contains("llm.mnn.weight"))
|
||||
#expect(names.contains("tokenizer.txt"))
|
||||
}
|
||||
|
||||
@Test func mnnFileURLUsesRepoPath() {
|
||||
let file = ModelFile(path: "config.json", bytes: 652)
|
||||
let url = ModelManifest.fileURL(for: .mnnLLM, file: file)
|
||||
#expect(url.absoluteString == "https://file.myv0.com/Qwen3.5-2B-MNN/config.json")
|
||||
}
|
||||
|
||||
@Test func excludesReadmeAndGitattributes() {
|
||||
for kind in [ModelKind.llm, .vl] {
|
||||
let names = ModelManifest.files(for: kind).map(\.path)
|
||||
|
||||
Reference in New Issue
Block a user