-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor image builds to put all of the hardware and platform selection logic into one place. #720
Changes from 3 commits
df456ae
38fc2b4
2570261
52600c1
cbe8581
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
FROM fedora:41 | ||
FROM quay.io/fedora/fedora:41 | ||
|
||
COPY ../scripts /scripts | ||
RUN chmod +x /scripts/*.sh && \ | ||
/scripts/build_llama_and_whisper.sh "asahi" | ||
COPY build_llama_and_whisper.sh / | ||
|
||
RUN chmod +x /build_llama_and_whisper.sh ; \ | ||
/build_llama_and_whisper.sh asahi |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#!/usr/bin/env bash | ||
|
||
# Bash does not easily pass arrays as a single arg to a function. So, make this a global var in the script. | ||
CMAKE_FLAGS="" | ||
LLAMA_CPP_CMAKE_FLAGS="" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we need a global variables, could we put local variables in main instead? Trying to keep everything scoped. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The styling changes aren't a blocker for merge, but why change it? We don't put "function" in front of the functions in any of the other shell scripts in the project, we don't use camelCase in any of the other shell scripts either. Now this is the odd shell script in terms of consistency 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I don't want to be the oddball... |
||
WHISPER_CPP_CMAKE_FLAGS="" | ||
|
||
function cmakeCheckWarnings() { | ||
awk -v rc=0 '/CMake Warning:/ { rc=1 } 1; END {exit rc}' | ||
} | ||
|
||
function cloneAndBuild() { | ||
local git_repo=${1} | ||
local git_sha=${2} | ||
local install_prefix=${3} | ||
local work_dir=$(mktemp -d) | ||
|
||
git clone ${git_repo} ${work_dir} | ||
cd ${work_dir} | ||
git submodule update --init --recursive | ||
git reset --hard ${git_sha} | ||
cmake -B build ${CMAKE_FLAGS[@]} 2>&1 | cmakeCheckWarnings | ||
cmake --build build --config Release -j$(nproc) -v 2>&1 | cmakeCheckWarnings | ||
cmake --install build --prefix ${install_prefix} 2>&1 | cmakeCheckWarnings | ||
cd - | ||
rm -rf ${work_dir} | ||
} | ||
|
||
function dnfPrepUbi() { | ||
|
||
local url="https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm" | ||
local uname_m=$(uname -m) | ||
|
||
dnf install -y ${url} | ||
crb enable # this is in epel-release, can only install epel-release via url | ||
dnf copr enable -y slp/mesa-krunkit epel-9-${uname_m} | ||
url="https://mirror.stream.centos.org/9-stream/AppStream/${uname_m}/os/" | ||
dnf config-manager --add-repo ${url} | ||
url="http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-Official" | ||
curl --retry 8 --retry-all-errors -o /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Official ${url} | ||
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-Official | ||
} | ||
|
||
function main() { | ||
set -ex | ||
|
||
local container_image=${1} | ||
local install_prefix=/usr | ||
local package_list | ||
local whisper_cpp_sha=${WHISPER_CPP_SHA:-8a9ad7844d6e2a10cddf4b92de4089d7ac2b14a9} | ||
local llama_cpp_sha=${LLAMA_CPP_SHA:-aa6fb1321333fae8853d0cdc26bcb5d438e650a1} | ||
local common_rpms=("python3" "python3-pip" "python3-argcomplete" "python3-dnf-plugin-versionlock" "gcc-c++" "cmake" "vim" "procps-ng" "git" "dnf-plugins-core" "libcurl-devel") | ||
local vulkan_rpms=("vulkan-headers" "vulkan-loader-devel" "vulkan-tools" "spirv-tools" "glslc" "glslang") | ||
local intel_rpms=("intel-oneapi-mkl-sycl-devel" "intel-oneapi-dnnl-devel" "intel-oneapi-compiler-dpcpp-cpp" "intel-level-zero" "oneapi-level-zero" "oneapi-level-zero-devel" "intel-compute-runtime") | ||
|
||
LLAMA_CPP_CMAKE_FLAGS+=("-DGGML_CCACHE=OFF" "-DGGML_NATIVE=OFF" "-DBUILD_SHARED_LIBS=NO" "-DLLAMA_CURL=ON") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This isn't right, we want BUILD_SHARE_LIBS for llama.cpp but not whisper.cpp There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think -DBUILD_SHARED_LIBS breaks for the intel-gpu build. I'll double check that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I bet that's why the rocm image got really big... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I think you got it, -DBUILD_SHARED_LIBS=NO end up in the libraries being duplicated in every single binary produced. The reason we do it for whisper.cpp is it uses some of the same libraries, with the same names, but with different versions sometimes, so one install will replace the library of the other, breaking whichever was installed first. whisper.cpp is a small project so we statically link that one to fix the issue. |
||
WHISPER_CPP_CMAKE_FLAGS+=("-DGGML_CCACHE=OFF" "-DGGML_NATIVE=OFF" "-DBUILD_SHARED_LIBS=NO") | ||
|
||
case ${container_image} in | ||
ramalama) | ||
dnf --enablerepo=ubi-9-appstream-rpms install -y "${common_rpms[@]}" | ||
dnfPrepUbi | ||
dnf --enablerepo=ubi-9-appstream-rpms install -y mesa-vulkan-drivers "${vulkan_rpms[@]}" | ||
LLAMA_CPP_CMAKE_FLAGS+=("-DGGML_KOMPUTE=ON" "-DKOMPUTE_OPT_DISABLE_VULKAN_VERSION_CHECK=ON") | ||
;; | ||
rocm) | ||
dnf --enablerepo=ubi-9-appstream-rpms install -y "${common_rpms[@]}" | ||
dnfPrepUbi | ||
dnf install -y "${vulkan_rpms[@]}" rocm-dev hipblas-devel rocblas-devel | ||
LLAMA_CPP_CMAKE_FLAGS+=("-DGGML_HIP=ON" "-DAMDGPU_TARGETS=${AMDGPU_TARGETS:-gfx1010,gfx1030,gfx1032,gfx1100,gfx1101,gfx1102}") | ||
WHISPER_CPP_CMAKE_FLAGS+=("-DGGML_HIP=ON" "-DAMDGPU_TARGETS=${AMDGPU_TARGETS:-gfx1010,gfx1030,gfx1032,gfx1100,gfx1101,gfx1102}") | ||
;; | ||
cuda) | ||
dnf install -y "${common_rpms[@]}" gcc-toolset-12 | ||
. /opt/rh/gcc-toolset-12/enable | ||
LLAMA_CPP_CMAKE_FLAGS+=("-DGGML_CUDA=ON" "-DCMAKE_EXE_LINKER_FLAGS=-Wl,--allow-shlib-undefined") | ||
WHISPER_CPP_CMAKE_FLAGS+=("-DGGML_CUDA=ON" "-DCMAKE_EXE_LINKER_FLAGS=-Wl,--allow-shlib-undefined") | ||
install_prefix=/llama-cpp | ||
;; | ||
vulkan) | ||
dnf --enablerepo=ubi-9-appstream-rpms install -y "${common_rpms[@]}" | ||
dnfPrepUbi | ||
dnf --enablerepo=ubi-9-appstream-rpms install -y mesa-vulkan-drivers "${vulkan_rpms[@]}" | ||
LLAMA_CPP_CMAKE_FLAGS+=("-DGGML_VULKAN=1") | ||
WHISPER_CPP_CMAKE_FLAGS+=("-DGGML_VULKAN=1") | ||
;; | ||
asahi) | ||
dnf copr enable -y @asahi/fedora-remix-branding | ||
dnf install -y asahi-repos | ||
dnf install -y mesa-vulkan-drivers "${vulkan_rpms[@]}" "${common_rpms[@]}" | ||
LLAMA_CPP_CMAKE_FLAGS+=("-DGGML_VULKAN=1") | ||
WHISPER_CPP_CMAKE_FLAGS+=("-DGGML_VULKAN=1") | ||
;; | ||
intel-gpu) | ||
dnf install -y ${common_rpms[@]} ${intel_rpms[@]} | ||
LLAMA_CPP_CMAKE_FLAGS+=("-DGGML_SYCL=ON" "-DCMAKE_C_COMPILER=icx" "-DCMAKE_CXX_COMPILER=icpx") | ||
WHISPER_CPP_CMAKE_FLAGS+=("-DGGML_SYCL=ON" "-DCMAKE_C_COMPILER=icx" "-DCMAKE_CXX_COMPILER=icpx") | ||
install_prefix=/llama-cpp | ||
source /opt/intel/oneapi/setvars.sh | ||
;; | ||
esac | ||
|
||
CMAKE_FLAGS+=("${WHISPER_CPP_CMAKE_FLAGS[@]}") | ||
cloneAndBuild https://github.com/ggerganov/whisper.cpp ${whisper_cpp_sha} ${install_prefix} | ||
CMAKE_FLAGS+=(${LLAMA_CPP_CMAKE_FLAGS[@]}) | ||
cloneAndBuild https://github.com/ggerganov/llama.cpp ${llama_cpp_sha} ${install_prefix} | ||
dnf -y clean all | ||
rm -rf /var/cache/*dnf* /opt/rocm-*/lib/*/library/*gfx9* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was where the bulk of the trimming was done for rocm in the past. Not sure why it's ballooned again. I'd revert this shell script back to it's original state and introduce just enough changes to get "intel-gpu" working with this script. There's no need to rewrite the whole script, it's asking for breakages. It's not making a reviewers job easy re-writing the whole thing 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Understood. It was a wild hair 🤓 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My intent is to see if we can prevent the build script from becoming a Rube Goldberg machine. The more logic that we have to drop into places based on different builds may get unmanageable. IMO, it's already a bit challenging to read. Natural entropy of code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure my attempt is much easier to read either though... |
||
ldconfig # needed for libraries | ||
|
||
} | ||
|
||
main "$@" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,23 @@ | ||
FROM quay.io/fedora/fedora:41 as builder | ||
|
||
COPY intel-gpu/oneAPI.repo /etc/yum.repos.d/ | ||
COPY build_llama_and_whisper.sh / | ||
|
||
RUN dnf install -y intel-opencl g++ cmake git tar libcurl-devel intel-oneapi-mkl-sycl-devel intel-oneapi-dnnl-devel intel-oneapi-compiler-dpcpp-cpp ; \ | ||
git clone https://github.com/ggerganov/llama.cpp.git -b b4523 ; \ | ||
cd llama.cpp ; \ | ||
mkdir -p build ; \ | ||
cd build ; \ | ||
source /opt/intel/oneapi/setvars.sh ; \ | ||
cmake .. -DGGML_SYCL=ON -DCMAKE_C_COMPILER=icx -DCMAKE_CXX_COMPILER=icpx -DLLAMA_CURL=ON -DGGML_CCACHE=OFF -DGGML_NATIVE=OFF ; \ | ||
cmake --build . --config Release -j -v ; \ | ||
cmake --install . --prefix /llama-cpp | ||
RUN chmod +x /build_llama_and_whisper.sh ; \ | ||
/build_llama_and_whisper.sh intel-gpu | ||
|
||
FROM quay.io/fedora/fedora:41 | ||
|
||
ENV LD_LIBRARY_PATH="/usr/local/lib64:/usr/local/lib/:/opt/intel/oneapi/mkl/2025.0/lib:/opt/intel/oneapi/compiler/2025.0/opt/compiler/lib:/opt/intel/oneapi/compiler/2025.0/lib/clang/19/lib:/opt/intel/oneapi/compiler/2025.0/lib:/opt/intel/oneapi/umf/0.9/lib:/opt/intel/oneapi/tbb/2022.0/lib:/opt/intel/oneapi/tcm/1.2/lib:/opt/intel/oneapi/redist/opt/compiler/lib:/opt/intel/oneapi/redist/lib/clang/19/lib:/opt/intel/oneapi/redist/lib:/opt/intel/oneapi/mkl/2025.0/lib:/opt/intel/oneapi/compiler/2025.0/opt/compiler/lib:/opt/intel/oneapi/compiler/2025.0/lib/clang/19/lib:/opt/intel/oneapi/compiler/2025.0/lib:/opt/intel/oneapi/umf/0.9/lib:/opt/intel/oneapi/tbb/2022.0/lib:/opt/intel/oneapi/tcm/1.2/lib:/opt/intel/oneapi/redist/opt/compiler/lib:/opt/intel/oneapi/redist/lib/clang/19/lib:/opt/intel/oneapi/redist/lib" | ||
|
||
COPY --from=builder /llama-cpp/bin/ /usr/local/bin/ | ||
COPY --from=builder /llama-cpp/lib/ /usr/local/lib/ | ||
COPY --from=builder /llama-cpp/lib64/ /usr/local/lib64/ | ||
COPY --from=builder /llama-cpp/include/ /usr/local/include/ | ||
COPY --from=builder /llama-cpp/ /usr/ | ||
COPY intel-gpu/oneAPI.repo /etc/yum.repos.d/ | ||
COPY --chown=0:0 intel-gpu/entrypoint.sh / | ||
|
||
RUN dnf install -y intel-opencl libcurl lspci clinfo intel-oneapi-runtime-compilers intel-oneapi-mkl-core intel-oneapi-mkl-sycl-blas intel-oneapi-runtime-dnnl ; \ | ||
RUN dnf install -y procps-ng python3 python3-pip python3-devel intel-level-zero oneapi-level-zero intel-compute-runtime libcurl lspci clinfo intel-oneapi-runtime-compilers intel-oneapi-mkl-core intel-oneapi-mkl-sycl-blas intel-oneapi-runtime-dnnl ; \ | ||
chown 0:0 /etc/passwd ; \ | ||
chown 0:0 /etc/group ; \ | ||
chmod g=u /etc/passwd /etc/group ; \ | ||
useradd -u 1000 -g render -G video -s /bin/bash -d /home/llama-user llama-user | ||
chmod g=u /etc/passwd /etc/group /home ; \ | ||
chmod +x /entrypoint.sh | ||
|
||
USER 10000 | ||
|
||
USER 1000 | ||
WORKDIR /home/llama-user | ||
ENTRYPOINT ["/entrypoint.sh"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#!/usr/bin/env bash | ||
|
||
if [ -z ${HOME} ] | ||
then | ||
export HOME=/home/llama-user | ||
fi | ||
|
||
# Create Home directory | ||
if [ ! -d "${HOME}" ] | ||
then | ||
mkdir -p "${HOME}" | ||
fi | ||
|
||
# Create User ID | ||
if ! whoami &> /dev/null | ||
then | ||
if [ -w /etc/passwd ] && [ -w /etc/group ] | ||
then | ||
echo "${USER_NAME:-llama-user}:x:$(id -u):0:${USER_NAME:-llama-user} user:${HOME}:/bin/bash" >> /etc/passwd | ||
echo "${USER_NAME:-llama-user}:x:$(id -u):" >> /etc/group | ||
render_group="$(cat /etc/group | grep 'render:x')" | ||
video_group="$(cat /etc/group | grep 'video:x')" | ||
render_group_new="${render_group}${USER_NAME:-llama-user}" | ||
video_group_new="${video_group}${USER_NAME:-llama-user}" | ||
sed "s|${render_group}|${render_group_new}|g" /etc/group > /tmp/group | ||
cat /tmp/group > /etc/group | ||
sed "s|${video_group}|${video_group_new}|g" /etc/group > /tmp/group | ||
cat /tmp/group > /etc/group | ||
fi | ||
fi | ||
|
||
# Configure Z shell | ||
if [ ! -f ${HOME}/.zshrc ] | ||
then | ||
(echo "source /opt/intel/oneapi/setvars.sh") > ${HOME}/.zshrc | ||
fi | ||
|
||
# Configure Bash shell | ||
if [ ! -f ${HOME}/.bashrc ] | ||
then | ||
(echo "source /opt/intel/oneapi/setvars.sh") > ${HOME}/.bashrc | ||
fi | ||
|
||
source /opt/intel/oneapi/setvars.sh | ||
|
||
exec "$@" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
FROM registry.access.redhat.com/ubi9/ubi:9.5-1736404036 | ||
|
||
COPY ../scripts /scripts | ||
RUN chmod +x /scripts/*.sh && \ | ||
/scripts/build_llama_and_whisper.sh "ramalama" | ||
COPY build_llama_and_whisper.sh / | ||
|
||
RUN chmod +x /build_llama_and_whisper.sh ; \ | ||
/build_llama_and_whisper.sh ramalama |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
FROM registry.access.redhat.com/ubi9/ubi:9.5-1736404036 | ||
ARG AMDGPU_TARGETS= | ||
ENV AMDGPU_TARGETS=${AMDGPU_TARGETS} | ||
|
||
COPY rocm/amdgpu.repo /etc/yum.repos.d/ | ||
COPY rocm/rocm.repo /etc/yum.repos.d/ | ||
COPY scripts /scripts | ||
|
||
ARG AMDGPU_TARGETS= | ||
ENV AMDGPU_TARGETS=${AMDGPU_TARGETS} | ||
RUN chmod +x /scripts/*.sh && \ | ||
/scripts/build_llama_and_whisper.sh "rocm" | ||
COPY build_llama_and_whisper.sh / | ||
|
||
RUN chmod +x /build_llama_and_whisper.sh ; \ | ||
/build_llama_and_whisper.sh rocm | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need to pass local variables as parameters in bash, they propagate to called functions, they just don't have global scope if that makes sense.