Repository navigation
fix: open model files with UTF-8 paths on Windows - #2144
Conversation
Paths reach the library as UTF-8 (argv_to_utf8 in the CLI, JSON in the server) but were opened with narrow APIs that Windows decodes in the ANSI code page: GetFileAttributesA/CreateFileA and std::fstream built from a std::string. A model under a non-ASCII directory could not be loaded. Open them through std::filesystem::u8path, as read_file_stamp already does, use the W APIs, and ggml_fopen for the GGUF writer.
|
Verified on the official master-970 release binaries (2f016e8) — this PR and companion #2145. Thank you. Datapoint (Windows 11, ANSI code page 1252, RX 6950 XT Vulkan, official Before (8cd731e): loading an SDXL checkpoint through a path with accented characters fails hard. Rig: a junction named with exit 1 — while the identical file loads fine through its non-accented path. Exactly the narrow-API ( After (2f016e8): the same accented path loads and renders normally, and the output at the same seed is pixel-identical to the ASCII-path run (0 differing pixels out of 262 144; the file hash differs only by the PNG metadata, which embeds the model path). The fix does not touch generation, as expected. Companion #2145 validated in the same run — its "before" behavior is nastier than a clean error, see the comment there. |
Companion of #2145 (the same fix in the CLI and server, for outputs and input images). The two PRs are independent and each builds on its own.
Problem
Paths reach the library as UTF-8: the CLI converts its arguments with
argv_to_utf8()and the server reads JSON. On Windows, the library thenopens them with narrow APIs that Windows decodes in the ANSI code page:
GetFileAttributesA/CreateFileA(file_exists,is_directory,MmapWrapper::create) andstd::ifstream/std::ofstream/std::fstreamconstructed from a
std::string. Any non-ASCII character in a path thennames a different file, so a model stored under e.g.
C:\Users\Hélène\orD:\modèles\cannot be loaded.read_file_stamp()inmodel_loader_files.cppalready usesstd::filesystem::u8path; this applies the same idiom to the other opens.Changes
src/core/util.cpp:file_exists,is_directoryandMmapWrapper::createuseGetFileAttributesW/CreateFileWonstd::filesystem::u8path(path).safetensors index and shard paths, the loader's non-mmap path),
--convertoutput, imatrix load/save, the HF tokenizer and tensordumps open their files through
std::filesystem::u8path(...).ggml_fopen, which already convertsUTF-8 to UTF-16 on Windows.
No public API change. On Linux/macOS
u8pathconstructs the same path asbefore.
Verification
Windows 11, MSVC 14.44,
-DSD_CUDA=OFF, master 8cd731e, FLUX.2 klein 4BQ4_0 (256x256, 4 steps, seed 1), the diffusion model hard-linked into a
directory named
modèles:--diffusion-model ...\modèles\klein.ggufloading diffusion model from '...' failed,get sd version from file failedKnown limitation
Zip-based torch checkpoints (
.ckpt/.pt) are opened by miniz, whichconverts UTF-8 to UTF-16 only under
_MSC_VER; a MinGW build still opensthem with narrow
fopen. That is inthirdparty/, so it is left out here.🤖 Generated with Claude Code
Summary by CodeRabbit