Support DeepSeek V4 Flash Vision Experimental

This commit is contained in:
Georg Bauer committed 2026-10-04 20:32:19 +02:00
1 parent 7c18e738cd
commit 9bbe12e6b3
52 files changed
+4988 -100

No files matched your search

+95 -2
View File
@@ -492,8 +492,8 @@ mod tests {
Some(ModelChoice::DeepSeekV4Flash0731)
);
assert!(ModelChoice::from_id("unknown").is_none());
assert_eq!(MODEL_CHOICES.len(), 5);
assert_eq!(MANAGED_ARTIFACTS.len(), 8);
assert_eq!(MODEL_CHOICES.len(), 6);
assert_eq!(MANAGED_ARTIFACTS.len(), 11);
assert_eq!(
ModelChoice::from_id("qwen3.8-flash-next"),
Some(ModelChoice::Qwen38FlashNext)
@@ -642,6 +642,99 @@ mod tests {
fs::remove_dir_all(models).unwrap();
}
#[test]
fn issue100_catalog_keeps_vision_and_dspark_checkpoint_specific() {
let model = ModelChoice::DeepSeekV4FlashVision;
assert_eq!(ModelChoice::from_id(model.id()), Some(model));
assert_eq!(
serde_json::from_str::<ModelChoice>(&serde_json::to_string(&model).unwrap()).unwrap(),
model
);
assert!(model.supports_vision() && model.supports_dspark());
assert!(!model.supports_integrated_mtp());
assert_eq!(model.artifacts(true).count(), 3);
assert_eq!(model.artifacts(false).count(), 2);
assert_ne!(
model.dspark_artifact().unwrap().sha256,
FLASH_0731_DSPARK.sha256
);
let defaults = crate::config::ModelPreferences::defaults_for(model);
assert!(defaults.speculative.dspark_enabled);
assert!(defaults.speculative.validate(model).is_ok());
let root = std::env::temp_dir().join(format!("issue100-catalog-{}", std::process::id()));
fs::create_dir_all(root.join(model.id())).unwrap();
// Sparse files exercise catalog and marker bookkeeping only. Real GGUF
// content and hashes are checked by the separate managed-intake test.
for artifact in [&FLASH_VISION, &FLASH_VISION_DSPARK] {
File::create(artifact.path(model, &root))
.unwrap()
.set_len(artifact.size)
.unwrap();
mark_verified(model, artifact, &root).unwrap();
}
assert!(!installed_models(&root).contains(&model));
let missing = engine_artifacts(model, true, &root);
assert!(
validate_engine_artifacts(model, true, &missing)
.unwrap_err()
.contains("requires its vision encoder")
);
File::create(FLASH_VISION_ENCODER.path(model, &root))
.unwrap()
.set_len(FLASH_VISION_ENCODER.size)
.unwrap();
mark_verified(model, &FLASH_VISION_ENCODER, &root).unwrap();
assert_eq!(installed_models(&root), [model]);
let mut artifacts = engine_artifacts(model, true, &root);
validate_engine_artifacts(model, true, &artifacts).unwrap();
artifacts.support = Some(FLASH_0731_DSPARK.path(ModelChoice::DeepSeekV4Flash0731, &root));
assert!(
validate_engine_artifacts(model, true, &artifacts)
.unwrap_err()
.contains("not the expected")
);
artifacts = engine_artifacts(model, false, &root);
artifacts.vision = Some(GLM53_FLASH_VISION.path(ModelChoice::Glm53Flash, &root));
assert!(
validate_engine_artifacts(model, false, &artifacts)
.unwrap_err()
.contains("not the expected")
);
fs::remove_dir_all(root).unwrap();
}
#[test]
#[ignore = "requires all three pinned Vision-Exp GGUF artifacts; performs full SHA256 and intake validation"]
fn issue100_managed_intake() {
let source = Path::new("local-eval-results/issue100-artifacts");
let root = Path::new("local-eval-results/issue100-managed");
let model = ModelChoice::DeepSeekV4FlashVision;
fs::create_dir_all(root.join(model.id())).unwrap();
for id in [
ManagedArtifactId::DeepSeekV4FlashVisionEncoder,
ManagedArtifactId::DeepSeekV4FlashVisionDspark,
ManagedArtifactId::DeepSeekV4FlashVision,
] {
let artifact = id.artifact();
let destination = artifact.path(model, root);
if !destination.exists() {
fs::hard_link(source.join(artifact.file_name), &destination).unwrap();
}
let verified = AtomicU64::new(0);
assert_eq!(
validate_managed_artifact(id, root, &AtomicBool::new(false), &verified).unwrap(),
DownloadOutcome::Complete
);
assert_eq!(verified.load(Ordering::Relaxed), artifact.size);
eprintln!("verified {} {} bytes", artifact.file_name, artifact.size);
}
assert_eq!(installed_models(root), [model]);
for dspark in [false, true] {
validate_engine_artifacts(model, dspark, &engine_artifacts(model, dspark, root))
.unwrap();
}
}
#[test]
fn verification_reports_bytes_read() {
let path = std::env::temp_dir().join(format!(