docker build not successful

用户使用 Ollama(版本 0.6.8,警告客户端版本 0.3.6),在拥有 16 块 NVIDIA A16 GPU 的服务器上,尝试修改 ml/backend/ggml/ggml/src/ggml-backend.cpp 中的 GGML_SCHED_MAX_BACKENDS 宏定义,然后执行 d

快速结论:在构建包含 Vulkan 后端的 Ollama Docker 镜像时,如果宿主机有 16 块 NVIDIA A16 GPU,默认的 GGML_SCHED_MAX_BACKENDS 值(16)不足以容纳全部 GPU 加 CPU,且 Dockerfile 中缺少必要的 Vulkan 开发包,导致构建失败。优先排查:① Dockerfile 中 Vulkan 相关依赖是否安装;② GGML_SCHED_MAX_BACKENDS 宏定义值是否大于等于 GPU 数量 + 1(CPU)。

问题场景

用户使用 Ollama(版本 0.6.8,警告客户端版本 0.3.6),在拥有 16 块 NVIDIA A16 GPU 的服务器上,尝试修改 ml/backend/ggml/ggml/src/ggml-backend.cpp 中的 GGML_SCHED_MAX_BACKENDS 宏定义,然后执行 docker build . 构建包含 Vulkan 后端的 Docker 镜像,构建过程在 Vulkan 阶段失败。

报错原文

15.28 gmake[1]: *** [CMakeFiles/Makefile2:767: ml/backend/ggml/ggml/src/ggml-vulkan/CMakeFiles/ggml-vulkan.dir/rule] Error 2
15.28 gmake: *** [Makefile:391: ggml-vulkan] Error 2
------
Dockerfile:121
--------------------
 120 |     FROM base AS vulkan
 121 | >>> RUN --mount=type=cache,target=/root/.ccache \
 122 | >>>     cmake --preset 'Vulkan' -DOLLAMA_RUNNER_DIR="vulkan" \
 123 | >>>         && cmake --build --parallel --preset 'Vulkan' \
 124 | >>>         && cmake --install build --component Vulkan --strip --parallel 8
 125 |
--------------------
ERROR: failed to solve: process "/bin/sh -c cmake --preset 'Vulkan' -DOLLAMA_RUNNER_DIR=\"vulkan\"         && cmake --build --parallel --preset 'Vulkan'         && cmake --install build --component Vulkan --strip --parallel 8" did not complete successfully: exit code: 2

原因分析

两个主要原因:

  • 缺少 Vulkan 依赖:默认的 DockerfileFROM base AS vulkan 阶段没有安装 Vulkan 头文件、加载器和 Mesa Vulkan 驱动,导致 ggml-vulkan 编译失败。
  • 宏定义错误或值不足:用户直接在 ggml-backend.cpp 中修改 GGML_SCHED_MAX_BACKENDS 时使用了错误的语法(缺少 # 前缀),且默认值 16 未考虑 CPU 算力。对于 16 块 GPU,至少需要设为 17(16 GPU + 1 CPU),否则编译时可能因 backend 数量超出限制而失败。

环境排查

  • Ollama 版本:0.6.8(客户端版本 0.3.6)
  • GPU:NVIDIA A16 (16 块)
  • CPU:Intel
  • 构建环境:Docker,基础镜像为 Fedora(使用 dnf 包管理器)
  • Vulkan 依赖:vulkan-headers, vulkan-loader-devel, mesa-vulkan-drivers, mesa-libGL-devel
  • CMake 参数:CMAKE_DEFINES 环境变量(如 -DGGML_SCHED_MAX_BACKENDS=17

解决步骤

  1. 修改 Dockerfile,在 FROM base AS vulkan 后添加 Vulkan 依赖安装:

    FROM base AS vulkan
    # 安装 Vulkan 运行时和开发加载器以支持 ggml-vulkan
    RUN dnf install -y \
          vulkan-headers \
          vulkan-loader-devel \
          mesa-vulkan-drivers \
          mesa-libGL-devel \
          && dnf clean all
    
    # 确保复制的 Vulkan SDK 库可被发现
    ENV LD_LIBRARY_PATH=/usr/local/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
    RUN ldconfig
    
    # 后续原生的编译命令保持不变
    RUN --mount=type=cache,target=/root/.ccache \
        cmake --preset 'Vulkan' -DOLLAMA_RUNNER_DIR="vulkan" \
        && cmake --build --parallel --preset 'Vulkan' \
        && cmake --install build --component Vulkan --strip --parallel 8
  2. 不要在源码文件中手动编辑宏,改用 CMAKE_DEFINES 构建参数传递:

    运行构建命令时,通过 --build-arg CMAKE_DEFINES 设置 GGML_SCHED_MAX_BACKENDS17(16 GPU + 1 CPU),以支持所有 GPU 和 CPU:

    docker build --build-arg PARALLEL=8 --no-cache --build-arg CMAKE_DEFINES="-DGGML_SCHED_MAX_BACKENDS=17" -t ollama-by-source .

    注意:如果仅设置 16 则对编译无修改;实际需要 17 或更高。

  3. 运行容器并验证 GPU 可见性:

    docker run -it --gpus all --device=/dev/dri --entrypoint /bin/bash ollama-by-source:latest
    # 在容器内执行
    nvidia-smi -L

    应列出全部 16 块 GPU。

  4. (可选)若希望模型跨所有 GPU 调度,设置环境变量 OLLAMA_SCHED_SPREAD=1

    可在运行容器时通过 -e OLLAMA_SCHED_SPREAD=1 传递,或在容器启动脚本中设置。该变量无需修改 C++ 文件。

验证方法

  • Docker 构建步骤执行结束,无 Error 2failed to solve 提示。
  • 容器内 nvidia-smi -L 输出所有 GPU(如 16 块 A16)。
  • Ollama 服务能正常加载并运行大模型(如 qwen3:30b),且日志中无 backend 不足相关错误。

参考来源

ollama/ollama #12703

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 16240

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注