@@ -1699,6 +1699,37 @@ static void ds4_gpu_model_views_clear(void) {
16991699 g_model_view_count = 0;
17001700}
17011701
1702+ /* Replace one model's view set without discarding auxiliary GGUF mappings.
1703+ * DeepSeek V4 vision keeps its encoder in a separate mmap. SSD streaming
1704+ * remaps receiver spans between prefill stages, so clearing the global view
1705+ * table here would also unmap the vision encoder before visual routing. */
1706+ static void ds4_gpu_model_views_remove_map(
1707+ const void *model_map,
1708+ uint64_t model_size) {
1709+ uint32_t out = 0;
1710+ for (uint32_t i = 0; i < g_model_view_count; i++) {
1711+ if (g_model_views[i].model_map == model_map &&
1712+ g_model_views[i].model_size == model_size) {
1713+ g_model_views[i].buffer = nil;
1714+ g_model_views[i].model_map = NULL;
1715+ g_model_views[i].model_size = 0;
1716+ g_model_views[i].model_offset = 0;
1717+ g_model_views[i].bytes = 0;
1718+ continue;
1719+ }
1720+ if (out != i) g_model_views[out] = g_model_views[i];
1721+ out++;
1722+ }
1723+ for (uint32_t i = out; i < g_model_view_count; i++) {
1724+ g_model_views[i].buffer = nil;
1725+ g_model_views[i].model_map = NULL;
1726+ g_model_views[i].model_size = 0;
1727+ g_model_views[i].model_offset = 0;
1728+ g_model_views[i].bytes = 0;
1729+ }
1730+ g_model_view_count = out;
1731+ }
1732+
17021733static void ds4_gpu_model_residency_clear(void) {
17031734#if TARGET_OS_OSX
17041735 if (@available(macOS 15.0, *)) {
@@ -11377,15 +11408,15 @@ int ds4_gpu_set_model_map_spans(
1137711408 max_tensor_bytes = ds4_gpu_effective_model_max_tensor_bytes(model_size, max_tensor_bytes);
1137811409
1137911410 ds4_gpu_model_residency_clear();
11380- ds4_gpu_model_views_clear( );
11411+ ds4_gpu_model_views_remove_map(model_map, model_size );
1138111412
1138211413 uint64_t mapped_total = 0;
1138311414 uint64_t first_offset = UINT64_MAX;
1138411415 for (uint32_t i = 0; i < count; i++) {
1138511416 if (offsets[i] > model_size || sizes[i] == 0 || sizes[i] > model_size - offsets[i]) {
1138611417 fprintf(stderr, "ds4: Metal model span %u is outside the GGUF mapping\n", i);
1138711418 ds4_gpu_model_residency_clear();
11388- ds4_gpu_model_views_clear( );
11419+ ds4_gpu_model_views_remove_map(model_map, model_size );
1138911420 return 0;
1139011421 }
1139111422 if (offsets[i] < first_offset) first_offset = offsets[i];
@@ -11399,13 +11430,13 @@ int ds4_gpu_set_model_map_spans(
1139911430 true,
1140011431 &mapped_total)) {
1140111432 ds4_gpu_model_residency_clear();
11402- ds4_gpu_model_views_clear( );
11433+ ds4_gpu_model_views_remove_map(model_map, model_size );
1140311434 return 0;
1140411435 }
1140511436 }
1140611437 if (!ds4_gpu_finish_model_views(t0, mapped_total, first_offset)) {
1140711438 ds4_gpu_model_residency_clear();
11408- ds4_gpu_model_views_clear( );
11439+ ds4_gpu_model_views_remove_map(model_map, model_size );
1140911440 return 0;
1141011441 }
1141111442 g_model_map_ptr = model_map;
0 commit comments