fix: prefer discrete GPUs in auto-fit device selection (#2259)

This commit is contained in:
leejet authored and GitHub committed 2026-11-02 01:09:36 +08:00
1 parent 5d33b1bd2b
commit 133087deb8
2 files changed
+23 -9

No files matched your search

+4 -1
View File
@@ -135,7 +135,10 @@ regardless of argument order, even with `--auto-fit on`.
Auto-fit preserves explicit `--backend` assignments, including per-module
assignments and device lists. For modules without a runtime assignment, it chooses
the GPU with the largest available memory budget (the first device on a tie).
the discrete GPU with the largest positive memory budget (the first device on a
tie), falling back to integrated GPUs when no discrete GPU has a positive budget.
An integrated GPU's shared system memory does not give it priority over a discrete
GPU. Explicit assignments such as `--backend Vulkan1` still select that device.
It then derives parameter placements from the model metadata, each module's
compute devices, and the remaining memory budgets. The chosen backend
specifications are printed.
+19 -8
View File
@@ -42,8 +42,9 @@ namespace sd::backend_fit {
struct Device {
std::string name;
std::string description;
int64_t free_bytes = 0;
int64_t budget_bytes = 0;
int64_t free_bytes = 0;
int64_t budget_bytes = 0;
enum ggml_backend_dev_type type = GGML_BACKEND_DEVICE_TYPE_GPU;
};
enum class ParamsLocation {
@@ -140,6 +141,7 @@ namespace sd::backend_fit {
Device device;
device.name = ggml_backend_dev_name(dev);
device.description = ggml_backend_dev_description(dev);
device.type = type;
size_t free_bytes = 0, total_bytes = 0;
ggml_backend_dev_memory(dev, &free_bytes, &total_bytes);
device.free_bytes = (int64_t)free_bytes;
@@ -193,14 +195,23 @@ namespace sd::backend_fit {
}
static size_t select_main_device(const std::vector<Device>& devices) {
size_t main_device = SIZE_MAX;
for (size_t di = 0; di < devices.size(); ++di) {
if (devices[di].budget_bytes > 0 &&
(main_device == SIZE_MAX || devices[di].budget_bytes > devices[main_device].budget_bytes)) {
main_device = di;
// Shared system memory must not make an integrated GPU outrank a discrete GPU.
for (bool discrete : {true, false}) {
size_t main_device = SIZE_MAX;
for (size_t di = 0; di < devices.size(); ++di) {
if ((devices[di].type == GGML_BACKEND_DEVICE_TYPE_GPU) != discrete) {
continue;
}
if (devices[di].budget_bytes > 0 &&
(main_device == SIZE_MAX || devices[di].budget_bytes > devices[main_device].budget_bytes)) {
main_device = di;
}
}
if (main_device != SIZE_MAX) {
return main_device;
}
}
return main_device;
return SIZE_MAX;
}
static Plan compute_plan(const std::vector<Component>& components,