Compare commits
1 Commits
ollama-bac
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b666d16db5 |
@@ -1,7 +1,7 @@
|
||||
version: 2.1
|
||||
setup: true
|
||||
orbs:
|
||||
path-filtering: circleci/path-filtering@1.1.0
|
||||
path-filtering: circleci/path-filtering@1.3.0
|
||||
|
||||
workflows:
|
||||
version: 2.1
|
||||
@@ -17,4 +17,6 @@ workflows:
|
||||
mapping: |
|
||||
.circleci/.* run-all-workflows true
|
||||
gpt4all-backend/.* run-all-workflows true
|
||||
gpt4all-bindings/python/.* run-python-workflow true
|
||||
gpt4all-bindings/typescript/.* run-ts-workflow true
|
||||
gpt4all-chat/.* run-chat-workflow true
|
||||
|
||||
@@ -8,9 +8,15 @@ parameters:
|
||||
run-all-workflows:
|
||||
type: boolean
|
||||
default: false
|
||||
run-python-workflow:
|
||||
type: boolean
|
||||
default: false
|
||||
run-chat-workflow:
|
||||
type: boolean
|
||||
default: false
|
||||
run-ts-workflow:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
job-macos-executor: &job-macos-executor
|
||||
macos:
|
||||
@@ -1260,6 +1266,25 @@ jobs:
|
||||
paths:
|
||||
- ../.ccache
|
||||
|
||||
build-ts-docs:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- node/install:
|
||||
node-version: "18.16"
|
||||
- run: node --version
|
||||
- run: corepack enable
|
||||
- node/install-packages:
|
||||
pkg-manager: npm
|
||||
app-dir: gpt4all-bindings/typescript
|
||||
override-ci-command: npm install --ignore-scripts
|
||||
- run:
|
||||
name: build docs ts yo
|
||||
command: |
|
||||
cd gpt4all-bindings/typescript
|
||||
npm run docs:build
|
||||
|
||||
deploy-docs:
|
||||
docker:
|
||||
- image: circleci/python:3.8
|
||||
@@ -1270,17 +1295,532 @@ jobs:
|
||||
command: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install python3 python3-pip
|
||||
sudo pip3 install -Ur requirements-docs.txt awscli
|
||||
sudo pip3 install awscli --upgrade
|
||||
sudo pip3 install mkdocs mkdocs-material mkautodoc 'mkdocstrings[python]' markdown-captions pillow cairosvg
|
||||
- run:
|
||||
name: Make Documentation
|
||||
command: mkdocs build
|
||||
command: |
|
||||
cd gpt4all-bindings/python
|
||||
mkdocs build
|
||||
- run:
|
||||
name: Deploy Documentation
|
||||
command: aws s3 sync --delete site/ s3://docs.gpt4all.io/
|
||||
command: |
|
||||
cd gpt4all-bindings/python
|
||||
aws s3 sync --delete site/ s3://docs.gpt4all.io/
|
||||
- run:
|
||||
name: Invalidate docs.gpt4all.io cloudfront
|
||||
command: aws cloudfront create-invalidation --distribution-id E1STQOW63QL2OH --paths "/*"
|
||||
|
||||
build-py-linux:
|
||||
machine:
|
||||
image: ubuntu-2204:current
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
keys:
|
||||
- ccache-gpt4all-linux-amd64-
|
||||
- run:
|
||||
<<: *job-linux-install-backend-deps
|
||||
- run:
|
||||
name: Build C library
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
export PATH=$PATH:/usr/local/cuda/bin
|
||||
git submodule update --init --recursive
|
||||
ccache -o "cache_dir=${PWD}/../.ccache" -o max_size=500M -p -z
|
||||
cd gpt4all-backend
|
||||
cmake -B build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_C_COMPILER=clang-19 \
|
||||
-DCMAKE_CXX_COMPILER=clang++-19 \
|
||||
-DCMAKE_CXX_COMPILER_AR=ar \
|
||||
-DCMAKE_CXX_COMPILER_RANLIB=ranlib \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CUDA_COMPILER_LAUNCHER=ccache \
|
||||
-DKOMPUTE_OPT_DISABLE_VULKAN_VERSION_CHECK=ON \
|
||||
-DCMAKE_CUDA_ARCHITECTURES='50-virtual;52-virtual;61-virtual;70-virtual;75-virtual'
|
||||
cmake --build build -j$(nproc)
|
||||
ccache -s
|
||||
- run:
|
||||
name: Build wheel
|
||||
command: |
|
||||
cd gpt4all-bindings/python/
|
||||
python setup.py bdist_wheel --plat-name=manylinux1_x86_64
|
||||
- store_artifacts:
|
||||
path: gpt4all-bindings/python/dist
|
||||
- save_cache:
|
||||
key: ccache-gpt4all-linux-amd64-{{ epoch }}
|
||||
when: always
|
||||
paths:
|
||||
- ../.ccache
|
||||
- persist_to_workspace:
|
||||
root: gpt4all-bindings/python/dist
|
||||
paths:
|
||||
- "*.whl"
|
||||
|
||||
build-py-macos:
|
||||
<<: *job-macos-executor
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
keys:
|
||||
- ccache-gpt4all-macos-
|
||||
- run:
|
||||
<<: *job-macos-install-deps
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: |
|
||||
pip install setuptools wheel cmake
|
||||
- run:
|
||||
name: Build C library
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
git submodule update --init # don't use --recursive because macOS doesn't use Kompute
|
||||
ccache -o "cache_dir=${PWD}/../.ccache" -o max_size=500M -p -z
|
||||
cd gpt4all-backend
|
||||
cmake -B build \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_C_COMPILER=/opt/homebrew/opt/llvm/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/opt/homebrew/opt/llvm/bin/clang++ \
|
||||
-DCMAKE_RANLIB=/usr/bin/ranlib \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DBUILD_UNIVERSAL=ON \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=12.6 \
|
||||
-DGGML_METAL_MACOSX_VERSION_MIN=12.6
|
||||
cmake --build build --parallel
|
||||
ccache -s
|
||||
- run:
|
||||
name: Build wheel
|
||||
command: |
|
||||
cd gpt4all-bindings/python
|
||||
python setup.py bdist_wheel --plat-name=macosx_10_15_universal2
|
||||
- store_artifacts:
|
||||
path: gpt4all-bindings/python/dist
|
||||
- save_cache:
|
||||
key: ccache-gpt4all-macos-{{ epoch }}
|
||||
when: always
|
||||
paths:
|
||||
- ../.ccache
|
||||
- persist_to_workspace:
|
||||
root: gpt4all-bindings/python/dist
|
||||
paths:
|
||||
- "*.whl"
|
||||
|
||||
build-py-windows:
|
||||
machine:
|
||||
image: windows-server-2022-gui:2024.04.1
|
||||
resource_class: windows.large
|
||||
shell: powershell.exe -ExecutionPolicy Bypass
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Update Submodules
|
||||
command: |
|
||||
git submodule sync
|
||||
git submodule update --init --recursive
|
||||
- restore_cache:
|
||||
keys:
|
||||
- ccache-gpt4all-win-amd64-
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command:
|
||||
choco install -y ccache cmake ninja wget --installargs 'ADD_CMAKE_TO_PATH=System'
|
||||
- run:
|
||||
name: Install VulkanSDK
|
||||
command: |
|
||||
wget.exe "https://sdk.lunarg.com/sdk/download/1.3.261.1/windows/VulkanSDK-1.3.261.1-Installer.exe"
|
||||
.\VulkanSDK-1.3.261.1-Installer.exe --accept-licenses --default-answer --confirm-command install
|
||||
- run:
|
||||
name: Install CUDA Toolkit
|
||||
command: |
|
||||
wget.exe "https://developer.download.nvidia.com/compute/cuda/11.8.0/network_installers/cuda_11.8.0_windows_network.exe"
|
||||
.\cuda_11.8.0_windows_network.exe -s cudart_11.8 nvcc_11.8 cublas_11.8 cublas_dev_11.8
|
||||
- run:
|
||||
name: Install Python dependencies
|
||||
command: pip install setuptools wheel cmake
|
||||
- run:
|
||||
name: Build C library
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
$vsInstallPath = & "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -property installationpath
|
||||
Import-Module "${vsInstallPath}\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
|
||||
Enter-VsDevShell -VsInstallPath "$vsInstallPath" -SkipAutomaticLocation -DevCmdArguments '-arch=x64 -no_logo'
|
||||
|
||||
$Env:PATH += ";C:\VulkanSDK\1.3.261.1\bin"
|
||||
$Env:VULKAN_SDK = "C:\VulkanSDK\1.3.261.1"
|
||||
ccache -o "cache_dir=${pwd}\..\.ccache" -o max_size=500M -p -z
|
||||
cd gpt4all-backend
|
||||
cmake -B build -G Ninja `
|
||||
-DCMAKE_BUILD_TYPE=Release `
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache `
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache `
|
||||
-DCMAKE_CUDA_COMPILER_LAUNCHER=ccache `
|
||||
-DKOMPUTE_OPT_DISABLE_VULKAN_VERSION_CHECK=ON `
|
||||
-DCMAKE_CUDA_ARCHITECTURES='50-virtual;52-virtual;61-virtual;70-virtual;75-virtual'
|
||||
cmake --build build --parallel
|
||||
ccache -s
|
||||
- run:
|
||||
name: Build wheel
|
||||
command: |
|
||||
cd gpt4all-bindings/python
|
||||
python setup.py bdist_wheel --plat-name=win_amd64
|
||||
- store_artifacts:
|
||||
path: gpt4all-bindings/python/dist
|
||||
- save_cache:
|
||||
key: ccache-gpt4all-win-amd64-{{ epoch }}
|
||||
when: always
|
||||
paths:
|
||||
- ..\.ccache
|
||||
- persist_to_workspace:
|
||||
root: gpt4all-bindings/python/dist
|
||||
paths:
|
||||
- "*.whl"
|
||||
|
||||
deploy-wheels:
|
||||
docker:
|
||||
- image: circleci/python:3.8
|
||||
steps:
|
||||
- setup_remote_docker
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential cmake
|
||||
pip install setuptools wheel twine
|
||||
- run:
|
||||
name: Upload Python package
|
||||
command: |
|
||||
twine upload /tmp/workspace/*.whl --username __token__ --password $PYPI_CRED
|
||||
- store_artifacts:
|
||||
path: /tmp/workspace
|
||||
|
||||
build-bindings-backend-linux:
|
||||
machine:
|
||||
image: ubuntu-2204:current
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Update Submodules
|
||||
command: |
|
||||
git submodule sync
|
||||
git submodule update --init --recursive
|
||||
- restore_cache:
|
||||
keys:
|
||||
- ccache-gpt4all-linux-amd64-
|
||||
- run:
|
||||
<<: *job-linux-install-backend-deps
|
||||
- run:
|
||||
name: Build Libraries
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
export PATH=$PATH:/usr/local/cuda/bin
|
||||
ccache -o "cache_dir=${PWD}/../.ccache" -o max_size=500M -p -z
|
||||
cd gpt4all-backend
|
||||
mkdir -p runtimes/build
|
||||
cd runtimes/build
|
||||
cmake ../.. -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_C_COMPILER=clang-19 \
|
||||
-DCMAKE_CXX_COMPILER=clang++-19 \
|
||||
-DCMAKE_CXX_COMPILER_AR=ar \
|
||||
-DCMAKE_CXX_COMPILER_RANLIB=ranlib \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CUDA_COMPILER_LAUNCHER=ccache \
|
||||
-DKOMPUTE_OPT_DISABLE_VULKAN_VERSION_CHECK=ON
|
||||
cmake --build . -j$(nproc)
|
||||
ccache -s
|
||||
mkdir ../linux-x64
|
||||
cp -L *.so ../linux-x64 # otherwise persist_to_workspace seems to mess symlinks
|
||||
- save_cache:
|
||||
key: ccache-gpt4all-linux-amd64-{{ epoch }}
|
||||
when: always
|
||||
paths:
|
||||
- ../.ccache
|
||||
- persist_to_workspace:
|
||||
root: gpt4all-backend
|
||||
paths:
|
||||
- runtimes/linux-x64/*.so
|
||||
|
||||
build-bindings-backend-macos:
|
||||
<<: *job-macos-executor
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Update Submodules
|
||||
command: |
|
||||
git submodule sync
|
||||
git submodule update --init --recursive
|
||||
- restore_cache:
|
||||
keys:
|
||||
- ccache-gpt4all-macos-
|
||||
- run:
|
||||
<<: *job-macos-install-deps
|
||||
- run:
|
||||
name: Build Libraries
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
ccache -o "cache_dir=${PWD}/../.ccache" -o max_size=500M -p -z
|
||||
cd gpt4all-backend
|
||||
mkdir -p runtimes/build
|
||||
cd runtimes/build
|
||||
cmake ../.. \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_C_COMPILER=/opt/homebrew/opt/llvm/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/opt/homebrew/opt/llvm/bin/clang++ \
|
||||
-DCMAKE_RANLIB=/usr/bin/ranlib \
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||
-DBUILD_UNIVERSAL=ON \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=12.6 \
|
||||
-DGGML_METAL_MACOSX_VERSION_MIN=12.6
|
||||
cmake --build . --parallel
|
||||
ccache -s
|
||||
mkdir ../osx-x64
|
||||
cp -L *.dylib ../osx-x64
|
||||
cp ../../llama.cpp-mainline/*.metal ../osx-x64
|
||||
ls ../osx-x64
|
||||
- save_cache:
|
||||
key: ccache-gpt4all-macos-{{ epoch }}
|
||||
when: always
|
||||
paths:
|
||||
- ../.ccache
|
||||
- persist_to_workspace:
|
||||
root: gpt4all-backend
|
||||
paths:
|
||||
- runtimes/osx-x64/*.dylib
|
||||
- runtimes/osx-x64/*.metal
|
||||
|
||||
build-bindings-backend-windows:
|
||||
machine:
|
||||
image: windows-server-2022-gui:2024.04.1
|
||||
resource_class: windows.large
|
||||
shell: powershell.exe -ExecutionPolicy Bypass
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Update Submodules
|
||||
command: |
|
||||
git submodule sync
|
||||
git submodule update --init --recursive
|
||||
- restore_cache:
|
||||
keys:
|
||||
- ccache-gpt4all-win-amd64-
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: |
|
||||
choco install -y ccache cmake ninja wget --installargs 'ADD_CMAKE_TO_PATH=System'
|
||||
- run:
|
||||
name: Install VulkanSDK
|
||||
command: |
|
||||
wget.exe "https://sdk.lunarg.com/sdk/download/1.3.261.1/windows/VulkanSDK-1.3.261.1-Installer.exe"
|
||||
.\VulkanSDK-1.3.261.1-Installer.exe --accept-licenses --default-answer --confirm-command install
|
||||
- run:
|
||||
name: Install CUDA Toolkit
|
||||
command: |
|
||||
wget.exe "https://developer.download.nvidia.com/compute/cuda/11.8.0/network_installers/cuda_11.8.0_windows_network.exe"
|
||||
.\cuda_11.8.0_windows_network.exe -s cudart_11.8 nvcc_11.8 cublas_11.8 cublas_dev_11.8
|
||||
- run:
|
||||
name: Build Libraries
|
||||
no_output_timeout: 30m
|
||||
command: |
|
||||
$vsInstallPath = & "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -property installationpath
|
||||
Import-Module "${vsInstallPath}\Common7\Tools\Microsoft.VisualStudio.DevShell.dll"
|
||||
Enter-VsDevShell -VsInstallPath "$vsInstallPath" -SkipAutomaticLocation -DevCmdArguments '-arch=x64 -no_logo'
|
||||
|
||||
$Env:Path += ";C:\VulkanSDK\1.3.261.1\bin"
|
||||
$Env:VULKAN_SDK = "C:\VulkanSDK\1.3.261.1"
|
||||
ccache -o "cache_dir=${pwd}\..\.ccache" -o max_size=500M -p -z
|
||||
cd gpt4all-backend
|
||||
mkdir runtimes/win-x64_msvc
|
||||
cd runtimes/win-x64_msvc
|
||||
cmake -S ../.. -B . -G Ninja `
|
||||
-DCMAKE_BUILD_TYPE=Release `
|
||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache `
|
||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache `
|
||||
-DCMAKE_CUDA_COMPILER_LAUNCHER=ccache `
|
||||
-DKOMPUTE_OPT_DISABLE_VULKAN_VERSION_CHECK=ON
|
||||
cmake --build . --parallel
|
||||
ccache -s
|
||||
cp bin/Release/*.dll .
|
||||
- save_cache:
|
||||
key: ccache-gpt4all-win-amd64-{{ epoch }}
|
||||
when: always
|
||||
paths:
|
||||
- ..\.ccache
|
||||
- persist_to_workspace:
|
||||
root: gpt4all-backend
|
||||
paths:
|
||||
- runtimes/win-x64_msvc/*.dll
|
||||
|
||||
build-nodejs-linux:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/gpt4all-backend
|
||||
- node/install:
|
||||
install-yarn: true
|
||||
node-version: "18.16"
|
||||
- run: node --version
|
||||
- run: corepack enable
|
||||
- node/install-packages:
|
||||
app-dir: gpt4all-bindings/typescript
|
||||
pkg-manager: yarn
|
||||
override-ci-command: yarn install
|
||||
- run:
|
||||
command: |
|
||||
cd gpt4all-bindings/typescript
|
||||
yarn prebuildify -t 18.16.0 --napi
|
||||
- run:
|
||||
command: |
|
||||
mkdir -p gpt4all-backend/prebuilds/linux-x64
|
||||
mkdir -p gpt4all-backend/runtimes/linux-x64
|
||||
cp /tmp/gpt4all-backend/runtimes/linux-x64/*-*.so gpt4all-backend/runtimes/linux-x64
|
||||
cp gpt4all-bindings/typescript/prebuilds/linux-x64/*.node gpt4all-backend/prebuilds/linux-x64
|
||||
- persist_to_workspace:
|
||||
root: gpt4all-backend
|
||||
paths:
|
||||
- prebuilds/linux-x64/*.node
|
||||
- runtimes/linux-x64/*-*.so
|
||||
|
||||
build-nodejs-macos:
|
||||
<<: *job-macos-executor
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/gpt4all-backend
|
||||
- node/install:
|
||||
install-yarn: true
|
||||
node-version: "18.16"
|
||||
- run: node --version
|
||||
- run: corepack enable
|
||||
- node/install-packages:
|
||||
app-dir: gpt4all-bindings/typescript
|
||||
pkg-manager: yarn
|
||||
override-ci-command: yarn install
|
||||
- run:
|
||||
command: |
|
||||
cd gpt4all-bindings/typescript
|
||||
yarn prebuildify -t 18.16.0 --napi
|
||||
- run:
|
||||
name: "Persisting all necessary things to workspace"
|
||||
command: |
|
||||
mkdir -p gpt4all-backend/prebuilds/darwin-x64
|
||||
mkdir -p gpt4all-backend/runtimes/darwin
|
||||
cp /tmp/gpt4all-backend/runtimes/osx-x64/*-*.* gpt4all-backend/runtimes/darwin
|
||||
cp gpt4all-bindings/typescript/prebuilds/darwin-x64/*.node gpt4all-backend/prebuilds/darwin-x64
|
||||
- persist_to_workspace:
|
||||
root: gpt4all-backend
|
||||
paths:
|
||||
- prebuilds/darwin-x64/*.node
|
||||
- runtimes/darwin/*-*.*
|
||||
|
||||
build-nodejs-windows:
|
||||
executor:
|
||||
name: win/default
|
||||
size: large
|
||||
shell: powershell.exe -ExecutionPolicy Bypass
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: /tmp/gpt4all-backend
|
||||
- run: choco install wget -y
|
||||
- run:
|
||||
command: |
|
||||
wget.exe "https://nodejs.org/dist/v18.16.0/node-v18.16.0-x86.msi" -P C:\Users\circleci\Downloads\
|
||||
MsiExec.exe /i C:\Users\circleci\Downloads\node-v18.16.0-x86.msi /qn
|
||||
- run:
|
||||
command: |
|
||||
Start-Process powershell -verb runAs -Args "-start GeneralProfile"
|
||||
nvm install 18.16.0
|
||||
nvm use 18.16.0
|
||||
- run: node --version
|
||||
- run: corepack enable
|
||||
- run:
|
||||
command: |
|
||||
npm install -g yarn
|
||||
cd gpt4all-bindings/typescript
|
||||
yarn install
|
||||
- run:
|
||||
command: |
|
||||
cd gpt4all-bindings/typescript
|
||||
yarn prebuildify -t 18.16.0 --napi
|
||||
- run:
|
||||
command: |
|
||||
mkdir -p gpt4all-backend/prebuilds/win32-x64
|
||||
mkdir -p gpt4all-backend/runtimes/win32-x64
|
||||
cp /tmp/gpt4all-backend/runtimes/win-x64_msvc/*-*.dll gpt4all-backend/runtimes/win32-x64
|
||||
cp gpt4all-bindings/typescript/prebuilds/win32-x64/*.node gpt4all-backend/prebuilds/win32-x64
|
||||
|
||||
- persist_to_workspace:
|
||||
root: gpt4all-backend
|
||||
paths:
|
||||
- prebuilds/win32-x64/*.node
|
||||
- runtimes/win32-x64/*-*.dll
|
||||
|
||||
deploy-npm-pkg:
|
||||
docker:
|
||||
- image: cimg/base:stable
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /tmp/gpt4all-backend
|
||||
- checkout
|
||||
- node/install:
|
||||
install-yarn: true
|
||||
node-version: "18.16"
|
||||
- run: node --version
|
||||
- run: corepack enable
|
||||
- run:
|
||||
command: |
|
||||
cd gpt4all-bindings/typescript
|
||||
# excluding llmodel. nodejs bindings dont need llmodel.dll
|
||||
mkdir -p runtimes/win32-x64/native
|
||||
mkdir -p prebuilds/win32-x64/
|
||||
cp /tmp/gpt4all-backend/runtimes/win-x64_msvc/*-*.dll runtimes/win32-x64/native/
|
||||
cp /tmp/gpt4all-backend/prebuilds/win32-x64/*.node prebuilds/win32-x64/
|
||||
|
||||
mkdir -p runtimes/linux-x64/native
|
||||
mkdir -p prebuilds/linux-x64/
|
||||
cp /tmp/gpt4all-backend/runtimes/linux-x64/*-*.so runtimes/linux-x64/native/
|
||||
cp /tmp/gpt4all-backend/prebuilds/linux-x64/*.node prebuilds/linux-x64/
|
||||
|
||||
# darwin has univeral runtime libraries
|
||||
mkdir -p runtimes/darwin/native
|
||||
mkdir -p prebuilds/darwin-x64/
|
||||
|
||||
cp /tmp/gpt4all-backend/runtimes/darwin/*-*.* runtimes/darwin/native/
|
||||
|
||||
cp /tmp/gpt4all-backend/prebuilds/darwin-x64/*.node prebuilds/darwin-x64/
|
||||
|
||||
# Fallback build if user is not on above prebuilds
|
||||
mv -f binding.ci.gyp binding.gyp
|
||||
|
||||
mkdir gpt4all-backend
|
||||
cd ../../gpt4all-backend
|
||||
mv llmodel.h llmodel.cpp llmodel_c.cpp llmodel_c.h sysinfo.h dlhandle.h ../gpt4all-bindings/typescript/gpt4all-backend/
|
||||
|
||||
# Test install
|
||||
- node/install-packages:
|
||||
app-dir: gpt4all-bindings/typescript
|
||||
pkg-manager: yarn
|
||||
override-ci-command: yarn install
|
||||
- run:
|
||||
command: |
|
||||
cd gpt4all-bindings/typescript
|
||||
yarn run test
|
||||
- run:
|
||||
command: |
|
||||
cd gpt4all-bindings/typescript
|
||||
npm set //registry.npmjs.org/:_authToken=$NPM_TOKEN
|
||||
npm publish
|
||||
|
||||
# only run a job on the main branch
|
||||
job_only_main: &job_only_main
|
||||
filters:
|
||||
@@ -1309,6 +1849,8 @@ workflows:
|
||||
not:
|
||||
or:
|
||||
- << pipeline.parameters.run-all-workflows >>
|
||||
- << pipeline.parameters.run-python-workflow >>
|
||||
- << pipeline.parameters.run-ts-workflow >>
|
||||
- << pipeline.parameters.run-chat-workflow >>
|
||||
- equal: [ << pipeline.trigger_source >>, scheduled_pipeline ]
|
||||
jobs:
|
||||
@@ -1537,9 +2079,87 @@ workflows:
|
||||
when:
|
||||
and:
|
||||
- equal: [ << pipeline.git.branch >>, main ]
|
||||
- << pipeline.parameters.run-all-workflows >>
|
||||
- or:
|
||||
- << pipeline.parameters.run-all-workflows >>
|
||||
- << pipeline.parameters.run-python-workflow >>
|
||||
- not:
|
||||
equal: [ << pipeline.trigger_source >>, scheduled_pipeline ]
|
||||
jobs:
|
||||
- deploy-docs:
|
||||
context: gpt4all
|
||||
build-python:
|
||||
when:
|
||||
and:
|
||||
- or: [ << pipeline.parameters.run-all-workflows >>, << pipeline.parameters.run-python-workflow >> ]
|
||||
- not:
|
||||
equal: [ << pipeline.trigger_source >>, scheduled_pipeline ]
|
||||
jobs:
|
||||
- pypi-hold:
|
||||
<<: *job_only_main
|
||||
type: approval
|
||||
- hold:
|
||||
type: approval
|
||||
- build-py-linux:
|
||||
requires:
|
||||
- hold
|
||||
- build-py-macos:
|
||||
requires:
|
||||
- hold
|
||||
- build-py-windows:
|
||||
requires:
|
||||
- hold
|
||||
- deploy-wheels:
|
||||
<<: *job_only_main
|
||||
context: gpt4all
|
||||
requires:
|
||||
- pypi-hold
|
||||
- build-py-windows
|
||||
- build-py-linux
|
||||
- build-py-macos
|
||||
build-bindings:
|
||||
when:
|
||||
and:
|
||||
- or: [ << pipeline.parameters.run-all-workflows >>, << pipeline.parameters.run-ts-workflow >> ]
|
||||
- not:
|
||||
equal: [ << pipeline.trigger_source >>, scheduled_pipeline ]
|
||||
jobs:
|
||||
- backend-hold:
|
||||
type: approval
|
||||
- nodejs-hold:
|
||||
type: approval
|
||||
- npm-hold:
|
||||
<<: *job_only_main
|
||||
type: approval
|
||||
- docs-hold:
|
||||
type: approval
|
||||
- build-bindings-backend-linux:
|
||||
requires:
|
||||
- backend-hold
|
||||
- build-bindings-backend-macos:
|
||||
requires:
|
||||
- backend-hold
|
||||
- build-bindings-backend-windows:
|
||||
requires:
|
||||
- backend-hold
|
||||
- build-nodejs-linux:
|
||||
requires:
|
||||
- nodejs-hold
|
||||
- build-bindings-backend-linux
|
||||
- build-nodejs-windows:
|
||||
requires:
|
||||
- nodejs-hold
|
||||
- build-bindings-backend-windows
|
||||
- build-nodejs-macos:
|
||||
requires:
|
||||
- nodejs-hold
|
||||
- build-bindings-backend-macos
|
||||
- build-ts-docs:
|
||||
requires:
|
||||
- docs-hold
|
||||
- deploy-npm-pkg:
|
||||
<<: *job_only_main
|
||||
requires:
|
||||
- npm-hold
|
||||
- build-nodejs-linux
|
||||
- build-nodejs-windows
|
||||
- build-nodejs-macos
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[codespell]
|
||||
ignore-words-list = blong, afterall, assistent, crasher, requestor, nam
|
||||
ignore-words-list = blong, afterall, assistent, crasher, requestor
|
||||
skip = ./.git,./gpt4all-chat/translations,*.pdf,*.svg,*.lock
|
||||
|
||||
35
.github/ISSUE_TEMPLATE/bindings-bug.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: "\U0001F6E0 Bindings Bug Report"
|
||||
about: A bug report for the GPT4All Bindings
|
||||
labels: ["bindings", "bug-unconfirmed"]
|
||||
---
|
||||
|
||||
<!-- Before creating a new issue, please make sure to take a few moments to check the issue tracker for existing issues about the bug. -->
|
||||
|
||||
### Bug Report
|
||||
|
||||
<!-- A clear and concise description of what the bug is. -->
|
||||
|
||||
### Example Code
|
||||
|
||||
<!-- Please provide a minimal code example that can be used to experience this issue. Delete this section if it does not apply. -->
|
||||
|
||||
### Steps to Reproduce
|
||||
|
||||
<!-- List the steps that should be taken to experience this issue. -->
|
||||
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
|
||||
### Expected Behavior
|
||||
|
||||
<!-- In a few words, what did you expect to happen? -->
|
||||
|
||||
### Your Environment
|
||||
|
||||
- Bindings version (e.g. "Version" from `pip show gpt4all`):
|
||||
- Operating System:
|
||||
- Chat model used (if applicable):
|
||||
|
||||
<!-- You can freely edit this text, please remove all the lines you believe are unnecessary. -->
|
||||
21
.gitmodules
vendored
@@ -1,16 +1,16 @@
|
||||
[submodule "gpt4all-backend-old/deps/llama.cpp-mainline"]
|
||||
path = gpt4all-backend-old/deps/llama.cpp-mainline
|
||||
[submodule "llama.cpp-mainline"]
|
||||
path = gpt4all-backend/deps/llama.cpp-mainline
|
||||
url = https://github.com/nomic-ai/llama.cpp.git
|
||||
branch = master
|
||||
branch = master
|
||||
[submodule "gpt4all-chat/usearch"]
|
||||
path = gpt4all-chat/deps/usearch
|
||||
url = https://github.com/nomic-ai/usearch.git
|
||||
[submodule "gpt4all-chat/deps/SingleApplication"]
|
||||
path = gpt4all-chat/deps/SingleApplication
|
||||
url = https://github.com/nomic-ai/SingleApplication.git
|
||||
[submodule "deps/fmt"]
|
||||
path = deps/fmt
|
||||
url = https://github.com/nomic-ai/fmt.git
|
||||
[submodule "gpt4all-chat/deps/fmt"]
|
||||
path = gpt4all-chat/deps/fmt
|
||||
url = https://github.com/fmtlib/fmt.git
|
||||
[submodule "gpt4all-chat/deps/DuckX"]
|
||||
path = gpt4all-chat/deps/DuckX
|
||||
url = https://github.com/nomic-ai/DuckX.git
|
||||
@@ -23,12 +23,3 @@
|
||||
[submodule "gpt4all-chat/deps/json"]
|
||||
path = gpt4all-chat/deps/json
|
||||
url = https://github.com/nlohmann/json.git
|
||||
[submodule "gpt4all-backend/deps/qcoro"]
|
||||
path = deps/qcoro
|
||||
url = https://github.com/nomic-ai/qcoro.git
|
||||
[submodule "gpt4all-backend/deps/date"]
|
||||
path = gpt4all-backend/deps/date
|
||||
url = https://github.com/HowardHinnant/date.git
|
||||
[submodule "gpt4all-chat/deps/generator"]
|
||||
path = gpt4all-chat/deps/generator
|
||||
url = https://github.com/TartanLlama/generator.git
|
||||
|
||||
@@ -29,6 +29,13 @@ Jared Van Bortel ([@cebtenzzre](https://github.com/cebtenzzre))<br/>
|
||||
E-mail: jared@nomic.ai<br/>
|
||||
Discord: `@cebtenzzre`
|
||||
- gpt4all-backend
|
||||
- Python binding
|
||||
- Python CLI app
|
||||
|
||||
Jacob Nguyen ([@jacoobes](https://github.com/jacoobes))<br/>
|
||||
Discord: `@jacoobes`<br/>
|
||||
E-mail: `jacoobes@sern.dev`
|
||||
- TypeScript binding
|
||||
|
||||
Dominik ([@cosmic-snow](https://github.com/cosmic-snow))<br/>
|
||||
E-mail: cosmic-snow@mailfence.com<br/>
|
||||
@@ -38,7 +45,7 @@ Discord: `@cosmic__snow`
|
||||
Max Cembalest ([@mcembalest](https://github.com/mcembalest))<br/>
|
||||
E-mail: max@nomic.ai<br/>
|
||||
Discord: `@maxcembalest.`
|
||||
- Official documentation (docs -> https://docs.gpt4all.io/)
|
||||
- Official documentation (gpt4all-bindings/python/docs -> https://docs.gpt4all.io/)
|
||||
|
||||
Thiago Ramos ([@thiagojramos](https://github.com/thiagojramos))<br/>
|
||||
E-mail: thiagojramos@outlook.com<br/>
|
||||
|
||||
26
README.md
@@ -32,7 +32,7 @@ GPT4All is made possible by our compute partner <a href="https://www.paperspace.
|
||||
|
||||
<p>
|
||||
— <a href="https://gpt4all.io/installers/gpt4all-installer-win64.exe">
|
||||
<img src="docs/assets/windows.png" style="height: 1em; width: auto" /> Windows Installer
|
||||
<img src="gpt4all-bindings/python/docs/assets/windows.png" style="height: 1em; width: auto" /> Windows Installer
|
||||
</a> —
|
||||
</p>
|
||||
<p>
|
||||
@@ -42,12 +42,12 @@ GPT4All is made possible by our compute partner <a href="https://www.paperspace.
|
||||
</p>
|
||||
<p>
|
||||
— <a href="https://gpt4all.io/installers/gpt4all-installer-darwin.dmg">
|
||||
<img src="docs/assets/mac.png" style="height: 1em; width: auto" /> macOS Installer
|
||||
<img src="gpt4all-bindings/python/docs/assets/mac.png" style="height: 1em; width: auto" /> macOS Installer
|
||||
</a> —
|
||||
</p>
|
||||
<p>
|
||||
— <a href="https://gpt4all.io/installers/gpt4all-installer-linux.run">
|
||||
<img src="docs/assets/ubuntu.svg" style="height: 1em; width: auto" /> Ubuntu Installer
|
||||
<img src="gpt4all-bindings/python/docs/assets/ubuntu.svg" style="height: 1em; width: auto" /> Ubuntu Installer
|
||||
</a> —
|
||||
</p>
|
||||
<p>
|
||||
@@ -74,6 +74,24 @@ See the full [System Requirements](gpt4all-chat/system_requirements.md) for more
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## Install GPT4All Python
|
||||
|
||||
`gpt4all` gives you access to LLMs with our Python client around [`llama.cpp`](https://github.com/ggerganov/llama.cpp) implementations.
|
||||
|
||||
Nomic contributes to open source software like [`llama.cpp`](https://github.com/ggerganov/llama.cpp) to make LLMs accessible and efficient **for all**.
|
||||
|
||||
```bash
|
||||
pip install gpt4all
|
||||
```
|
||||
|
||||
```python
|
||||
from gpt4all import GPT4All
|
||||
model = GPT4All("Meta-Llama-3-8B-Instruct.Q4_0.gguf") # downloads / loads a 4.66GB LLM
|
||||
with model.chat_session():
|
||||
print(model.generate("How can I run LLMs efficiently on my laptop?", max_tokens=1024))
|
||||
```
|
||||
|
||||
|
||||
## Integrations
|
||||
|
||||
:parrot::link: [Langchain](https://python.langchain.com/v0.2/docs/integrations/providers/gpt4all/)
|
||||
@@ -101,7 +119,7 @@ Please see CONTRIBUTING.md and follow the issues, bug reports, and PR markdown t
|
||||
|
||||
Check project discord, with project owners, or through existing issues/PRs to avoid duplicate work.
|
||||
Please make sure to tag all of the above with relevant project identifiers or your contribution could potentially get lost.
|
||||
Example tags: `backend`, `documentation`, etc.
|
||||
Example tags: `backend`, `bindings`, `python-bindings`, `documentation`, etc.
|
||||
|
||||
## Citation
|
||||
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
# enable color diagnostics with ninja
|
||||
if (CMAKE_GENERATOR STREQUAL Ninja AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
add_compile_options(-fdiagnostics-color=always)
|
||||
endif()
|
||||
|
||||
function(gpt4all_add_warning_options target)
|
||||
if (MSVC)
|
||||
return()
|
||||
|
||||
22
deps/CMakeLists.txt
vendored
@@ -1,22 +0,0 @@
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
set(FMT_INSTALL OFF)
|
||||
add_subdirectory(fmt)
|
||||
|
||||
set(BUILD_TESTING OFF)
|
||||
set(QCORO_BUILD_EXAMPLES OFF)
|
||||
set(QCORO_WITH_QTDBUS OFF)
|
||||
set(QCORO_WITH_QTWEBSOCKETS OFF)
|
||||
set(QCORO_WITH_QTQUICK OFF)
|
||||
set(QCORO_WITH_QTTEST OFF)
|
||||
add_subdirectory(qcoro)
|
||||
|
||||
set(GPT4ALL_BOOST_TAG 1.87.0)
|
||||
FetchContent_Declare(
|
||||
boost
|
||||
URL "https://github.com/boostorg/boost/releases/download/boost-${GPT4ALL_BOOST_TAG}/boost-${GPT4ALL_BOOST_TAG}-cmake.tar.xz"
|
||||
URL_HASH "SHA256=7da75f171837577a52bbf217e17f8ea576c7c246e4594d617bfde7fafd408be5"
|
||||
)
|
||||
|
||||
set(BOOST_INCLUDE_LIBRARIES json describe system)
|
||||
FetchContent_MakeAvailable(boost)
|
||||
1
deps/fmt
vendored
1
deps/qcoro
vendored
@@ -1,189 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.23) # for FILE_SET
|
||||
|
||||
include(../common/common.cmake)
|
||||
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
if (APPLE)
|
||||
option(BUILD_UNIVERSAL "Build a Universal binary on macOS" ON)
|
||||
else()
|
||||
option(LLMODEL_KOMPUTE "llmodel: use Kompute" ON)
|
||||
option(LLMODEL_VULKAN "llmodel: use Vulkan" OFF)
|
||||
option(LLMODEL_CUDA "llmodel: use CUDA" ON)
|
||||
option(LLMODEL_ROCM "llmodel: use ROCm" OFF)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
if (BUILD_UNIVERSAL)
|
||||
# Build a Universal binary on macOS
|
||||
# This requires that the found Qt library is compiled as Universal binaries.
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
|
||||
else()
|
||||
# Build for the host architecture on macOS
|
||||
if (NOT CMAKE_OSX_ARCHITECTURES)
|
||||
set(CMAKE_OSX_ARCHITECTURES "${CMAKE_HOST_SYSTEM_PROCESSOR}" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Include the binary directory for the generated header file
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
set(LLMODEL_VERSION_MAJOR 0)
|
||||
set(LLMODEL_VERSION_MINOR 5)
|
||||
set(LLMODEL_VERSION_PATCH 0)
|
||||
set(LLMODEL_VERSION "${LLMODEL_VERSION_MAJOR}.${LLMODEL_VERSION_MINOR}.${LLMODEL_VERSION_PATCH}")
|
||||
project(llmodel VERSION ${LLMODEL_VERSION} LANGUAGES CXX C)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
|
||||
# Check for IPO support
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_ERROR)
|
||||
if (NOT IPO_SUPPORTED)
|
||||
message(WARNING "Interprocedural optimization is not supported by your toolchain! This will lead to bigger file sizes and worse performance: ${IPO_ERROR}")
|
||||
else()
|
||||
message(STATUS "Interprocedural optimization support detected")
|
||||
endif()
|
||||
|
||||
set(DIRECTORY deps/llama.cpp-mainline)
|
||||
include(llama.cpp.cmake)
|
||||
|
||||
set(BUILD_VARIANTS)
|
||||
if (APPLE)
|
||||
list(APPEND BUILD_VARIANTS metal)
|
||||
endif()
|
||||
if (LLMODEL_KOMPUTE)
|
||||
list(APPEND BUILD_VARIANTS kompute kompute-avxonly)
|
||||
else()
|
||||
list(PREPEND BUILD_VARIANTS cpu cpu-avxonly)
|
||||
endif()
|
||||
if (LLMODEL_VULKAN)
|
||||
list(APPEND BUILD_VARIANTS vulkan vulkan-avxonly)
|
||||
endif()
|
||||
if (LLMODEL_CUDA)
|
||||
cmake_minimum_required(VERSION 3.18) # for CMAKE_CUDA_ARCHITECTURES
|
||||
|
||||
# Defaults must be set before enable_language(CUDA).
|
||||
# Keep this in sync with the arch list in ggml/src/CMakeLists.txt (plus 5.0 for non-F16 branch).
|
||||
if (NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
|
||||
# 52 == lowest CUDA 12 standard
|
||||
# 60 == f16 CUDA intrinsics
|
||||
# 61 == integer CUDA intrinsics
|
||||
# 70 == compute capability at which unrolling a loop in mul_mat_q kernels is faster
|
||||
if (GGML_CUDA_F16 OR GGML_CUDA_DMMV_F16)
|
||||
set(CMAKE_CUDA_ARCHITECTURES "60;61;70;75") # needed for f16 CUDA intrinsics
|
||||
else()
|
||||
set(CMAKE_CUDA_ARCHITECTURES "50;52;61;70;75") # lowest CUDA 12 standard + lowest for integer intrinsics
|
||||
#set(CMAKE_CUDA_ARCHITECTURES "OFF") # use this to compile much faster, but only F16 models work
|
||||
endif()
|
||||
endif()
|
||||
message(STATUS "Using CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}")
|
||||
|
||||
include(CheckLanguage)
|
||||
check_language(CUDA)
|
||||
if (NOT CMAKE_CUDA_COMPILER)
|
||||
message(WARNING "CUDA Toolkit not found. To build without CUDA, use -DLLMODEL_CUDA=OFF.")
|
||||
endif()
|
||||
enable_language(CUDA)
|
||||
list(APPEND BUILD_VARIANTS cuda cuda-avxonly)
|
||||
endif()
|
||||
if (LLMODEL_ROCM)
|
||||
enable_language(HIP)
|
||||
list(APPEND BUILD_VARIANTS rocm rocm-avxonly)
|
||||
endif()
|
||||
|
||||
# Go through each build variant
|
||||
foreach(BUILD_VARIANT IN LISTS BUILD_VARIANTS)
|
||||
# Determine flags
|
||||
if (BUILD_VARIANT MATCHES avxonly)
|
||||
set(GPT4ALL_ALLOW_NON_AVX OFF)
|
||||
else()
|
||||
set(GPT4ALL_ALLOW_NON_AVX ON)
|
||||
endif()
|
||||
set(GGML_AVX2 ${GPT4ALL_ALLOW_NON_AVX})
|
||||
set(GGML_F16C ${GPT4ALL_ALLOW_NON_AVX})
|
||||
set(GGML_FMA ${GPT4ALL_ALLOW_NON_AVX})
|
||||
|
||||
set(GGML_METAL OFF)
|
||||
set(GGML_KOMPUTE OFF)
|
||||
set(GGML_VULKAN OFF)
|
||||
set(GGML_CUDA OFF)
|
||||
set(GGML_ROCM OFF)
|
||||
if (BUILD_VARIANT MATCHES metal)
|
||||
set(GGML_METAL ON)
|
||||
elseif (BUILD_VARIANT MATCHES kompute)
|
||||
set(GGML_KOMPUTE ON)
|
||||
elseif (BUILD_VARIANT MATCHES vulkan)
|
||||
set(GGML_VULKAN ON)
|
||||
elseif (BUILD_VARIANT MATCHES cuda)
|
||||
set(GGML_CUDA ON)
|
||||
elseif (BUILD_VARIANT MATCHES rocm)
|
||||
set(GGML_HIPBLAS ON)
|
||||
endif()
|
||||
|
||||
# Include GGML
|
||||
include_ggml(-mainline-${BUILD_VARIANT})
|
||||
|
||||
if (BUILD_VARIANT MATCHES metal)
|
||||
set(GGML_METALLIB "${GGML_METALLIB}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
# Function for preparing individual implementations
|
||||
function(prepare_target TARGET_NAME BASE_LIB)
|
||||
set(TARGET_NAME ${TARGET_NAME}-${BUILD_VARIANT})
|
||||
message(STATUS "Configuring model implementation target ${TARGET_NAME}")
|
||||
# Link to ggml/llama
|
||||
target_link_libraries(${TARGET_NAME}
|
||||
PRIVATE ${BASE_LIB}-${BUILD_VARIANT})
|
||||
# Let it know about its build variant
|
||||
target_compile_definitions(${TARGET_NAME}
|
||||
PRIVATE GGML_BUILD_VARIANT="${BUILD_VARIANT}")
|
||||
# Enable IPO if possible
|
||||
# FIXME: Doesn't work with msvc reliably. See https://github.com/nomic-ai/gpt4all/issues/841
|
||||
# set_property(TARGET ${TARGET_NAME}
|
||||
# PROPERTY INTERPROCEDURAL_OPTIMIZATION ${IPO_SUPPORTED})
|
||||
endfunction()
|
||||
|
||||
# Add each individual implementations
|
||||
add_library(llamamodel-mainline-${BUILD_VARIANT} SHARED
|
||||
src/llamamodel.cpp src/llmodel_shared.cpp)
|
||||
gpt4all_add_warning_options(llamamodel-mainline-${BUILD_VARIANT})
|
||||
target_compile_definitions(llamamodel-mainline-${BUILD_VARIANT} PRIVATE
|
||||
LLAMA_VERSIONS=>=3 LLAMA_DATE=999999)
|
||||
target_include_directories(llamamodel-mainline-${BUILD_VARIANT} PRIVATE
|
||||
src include/gpt4all-backend
|
||||
)
|
||||
prepare_target(llamamodel-mainline llama-mainline)
|
||||
|
||||
if (NOT PROJECT_IS_TOP_LEVEL AND BUILD_VARIANT STREQUAL cuda)
|
||||
set(CUDAToolkit_BIN_DIR ${CUDAToolkit_BIN_DIR} PARENT_SCOPE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
add_library(llmodel
|
||||
src/dlhandle.cpp
|
||||
src/llmodel.cpp
|
||||
src/llmodel_c.cpp
|
||||
src/llmodel_shared.cpp
|
||||
)
|
||||
gpt4all_add_warning_options(llmodel)
|
||||
target_sources(llmodel PUBLIC
|
||||
FILE_SET public_headers TYPE HEADERS BASE_DIRS include
|
||||
FILES include/gpt4all-backend/llmodel.h
|
||||
include/gpt4all-backend/llmodel_c.h
|
||||
include/gpt4all-backend/sysinfo.h
|
||||
)
|
||||
target_compile_definitions(llmodel PRIVATE LIB_FILE_EXT="${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
target_include_directories(llmodel PRIVATE src include/gpt4all-backend)
|
||||
|
||||
set_target_properties(llmodel PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR})
|
||||
|
||||
set(COMPONENT_NAME_MAIN ${PROJECT_NAME})
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install)
|
||||
@@ -1,10 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.28...3.31)
|
||||
project(gpt4all-backend-test VERSION 0.1 LANGUAGES CXX)
|
||||
|
||||
set(G4A_TEST_OLLAMA_URL "http://localhost:11434/" CACHE STRING "The base URL of the Ollama server to use.")
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||
include(../common/common.cmake)
|
||||
|
||||
add_subdirectory(../gpt4all-backend gpt4all-backend)
|
||||
add_subdirectory(src)
|
||||
@@ -1,15 +0,0 @@
|
||||
set(TARGET test-backend)
|
||||
|
||||
configure_file(config.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/config.h")
|
||||
|
||||
add_executable(${TARGET}
|
||||
main.cpp
|
||||
)
|
||||
target_compile_features(${TARGET} PUBLIC cxx_std_23)
|
||||
target_include_directories(${TARGET} PRIVATE
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/include"
|
||||
)
|
||||
gpt4all_add_warning_options(${TARGET})
|
||||
target_link_libraries(${TARGET} PRIVATE
|
||||
gpt4all-backend
|
||||
)
|
||||
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
||||
|
||||
inline const QString OLLAMA_URL = QStringLiteral("@G4A_TEST_OLLAMA_URL@");
|
||||
@@ -1,70 +0,0 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "pretty.h"
|
||||
|
||||
#include <QCoro/QCoroTask> // IWYU pragma: keep
|
||||
#include <boost/json.hpp>
|
||||
#include <fmt/base.h>
|
||||
#include <gpt4all-backend/formatters.h> // IWYU pragma: keep
|
||||
#include <gpt4all-backend/ollama-client.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QTimer>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#include <coroutine>
|
||||
#include <expected>
|
||||
#include <variant>
|
||||
|
||||
namespace json = boost::json;
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
using gpt4all::backend::OllamaClient;
|
||||
|
||||
|
||||
template <typename T>
|
||||
static std::string to_json(const T &value)
|
||||
{ return pretty_print(json::value_from(value)); }
|
||||
|
||||
static void run()
|
||||
{
|
||||
fmt::print("Connecting to server at {}\n", OLLAMA_URL);
|
||||
OllamaClient provider(OLLAMA_URL);
|
||||
|
||||
auto versionResp = QCoro::waitFor(provider.version());
|
||||
if (versionResp) {
|
||||
fmt::print("Version response: {}\n", to_json(*versionResp));
|
||||
} else {
|
||||
fmt::print("Error retrieving version: {}\n", versionResp.error().errorString);
|
||||
return QCoreApplication::exit(1);
|
||||
}
|
||||
|
||||
auto modelsResponse = QCoro::waitFor(provider.list());
|
||||
if (modelsResponse) {
|
||||
fmt::print("Available models:\n");
|
||||
for (const auto & model : modelsResponse->models)
|
||||
fmt::print("{}\n", model.model);
|
||||
if (!modelsResponse->models.empty())
|
||||
fmt::print("First model: {}\n", to_json(modelsResponse->models.front()));
|
||||
} else {
|
||||
fmt::print("Error retrieving available models: {}\n", modelsResponse.error().errorString);
|
||||
return QCoreApplication::exit(1);
|
||||
}
|
||||
|
||||
auto showResponse = QCoro::waitFor(provider.show({ .model = "DeepSeek-R1-Distill-Llama-70B-Q4_K_S" }));
|
||||
if (showResponse) {
|
||||
fmt::print("Show response: {}\n", to_json(*showResponse));
|
||||
} else {
|
||||
fmt::print("Error retrieving model info: {}\n", showResponse.error().errorString);
|
||||
return QCoreApplication::exit(1);
|
||||
}
|
||||
|
||||
QCoreApplication::exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
QTimer::singleShot(0, &run);
|
||||
return app.exec();
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/json.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
|
||||
inline void pretty_print( std::ostream& os, boost::json::value const& jv, std::string* indent = nullptr )
|
||||
{
|
||||
std::string indent_;
|
||||
if(! indent)
|
||||
indent = &indent_;
|
||||
switch(jv.kind())
|
||||
{
|
||||
case boost::json::kind::object:
|
||||
{
|
||||
os << "{\n";
|
||||
indent->append(4, ' ');
|
||||
auto const& obj = jv.get_object();
|
||||
if(! obj.empty())
|
||||
{
|
||||
auto it = obj.begin();
|
||||
for(;;)
|
||||
{
|
||||
os << *indent << boost::json::serialize(it->key()) << ": ";
|
||||
pretty_print(os, it->value(), indent);
|
||||
if(++it == obj.end())
|
||||
break;
|
||||
os << ",\n";
|
||||
}
|
||||
}
|
||||
os << "\n";
|
||||
indent->resize(indent->size() - 4);
|
||||
os << *indent << "}";
|
||||
break;
|
||||
}
|
||||
|
||||
case boost::json::kind::array:
|
||||
{
|
||||
os << "[\n";
|
||||
indent->append(4, ' ');
|
||||
auto const& arr = jv.get_array();
|
||||
if(! arr.empty())
|
||||
{
|
||||
auto it = arr.begin();
|
||||
for(;;)
|
||||
{
|
||||
os << *indent;
|
||||
pretty_print( os, *it, indent);
|
||||
if(++it == arr.end())
|
||||
break;
|
||||
os << ",\n";
|
||||
}
|
||||
}
|
||||
os << "\n";
|
||||
indent->resize(indent->size() - 4);
|
||||
os << *indent << "]";
|
||||
break;
|
||||
}
|
||||
|
||||
case boost::json::kind::string:
|
||||
{
|
||||
os << boost::json::serialize(jv.get_string());
|
||||
break;
|
||||
}
|
||||
|
||||
case boost::json::kind::uint64:
|
||||
case boost::json::kind::int64:
|
||||
case boost::json::kind::double_:
|
||||
os << jv;
|
||||
break;
|
||||
|
||||
case boost::json::kind::bool_:
|
||||
if(jv.get_bool())
|
||||
os << "true";
|
||||
else
|
||||
os << "false";
|
||||
break;
|
||||
|
||||
case boost::json::kind::null:
|
||||
os << "null";
|
||||
break;
|
||||
}
|
||||
|
||||
if(indent->empty())
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
inline std::string pretty_print( boost::json::value const& jv, std::string* indent = nullptr )
|
||||
{
|
||||
std::ostringstream ss;
|
||||
pretty_print(ss, jv, indent);
|
||||
return ss.str();
|
||||
}
|
||||
@@ -1,22 +1,189 @@
|
||||
cmake_minimum_required(VERSION 3.28...3.31)
|
||||
project(gpt4all-backend VERSION 0.1 LANGUAGES CXX)
|
||||
cmake_minimum_required(VERSION 3.23) # for FILE_SET
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23) # make sure fmt is compiled with the same C++ version as us
|
||||
include(../common/common.cmake)
|
||||
|
||||
find_package(Qt6 6.8 COMPONENTS Concurrent Core Network REQUIRED)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
add_subdirectory(../deps common_deps)
|
||||
add_subdirectory(deps)
|
||||
add_subdirectory(src)
|
||||
if (APPLE)
|
||||
option(BUILD_UNIVERSAL "Build a Universal binary on macOS" ON)
|
||||
else()
|
||||
option(LLMODEL_KOMPUTE "llmodel: use Kompute" ON)
|
||||
option(LLMODEL_VULKAN "llmodel: use Vulkan" OFF)
|
||||
option(LLMODEL_CUDA "llmodel: use CUDA" ON)
|
||||
option(LLMODEL_ROCM "llmodel: use ROCm" OFF)
|
||||
endif()
|
||||
|
||||
target_sources(gpt4all-backend PUBLIC
|
||||
FILE_SET public_headers TYPE HEADERS BASE_DIRS include FILES
|
||||
include/gpt4all-backend/formatters.h
|
||||
include/gpt4all-backend/generation-params.h
|
||||
include/gpt4all-backend/json-helpers.h
|
||||
include/gpt4all-backend/ollama-client.h
|
||||
include/gpt4all-backend/ollama-model.h
|
||||
include/gpt4all-backend/ollama-types.h
|
||||
include/gpt4all-backend/rest.h
|
||||
if (APPLE)
|
||||
if (BUILD_UNIVERSAL)
|
||||
# Build a Universal binary on macOS
|
||||
# This requires that the found Qt library is compiled as Universal binaries.
|
||||
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "" FORCE)
|
||||
else()
|
||||
# Build for the host architecture on macOS
|
||||
if (NOT CMAKE_OSX_ARCHITECTURES)
|
||||
set(CMAKE_OSX_ARCHITECTURES "${CMAKE_HOST_SYSTEM_PROCESSOR}" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Include the binary directory for the generated header file
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
set(LLMODEL_VERSION_MAJOR 0)
|
||||
set(LLMODEL_VERSION_MINOR 5)
|
||||
set(LLMODEL_VERSION_PATCH 0)
|
||||
set(LLMODEL_VERSION "${LLMODEL_VERSION_MAJOR}.${LLMODEL_VERSION_MINOR}.${LLMODEL_VERSION_PATCH}")
|
||||
project(llmodel VERSION ${LLMODEL_VERSION} LANGUAGES CXX C)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
|
||||
# Check for IPO support
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT IPO_SUPPORTED OUTPUT IPO_ERROR)
|
||||
if (NOT IPO_SUPPORTED)
|
||||
message(WARNING "Interprocedural optimization is not supported by your toolchain! This will lead to bigger file sizes and worse performance: ${IPO_ERROR}")
|
||||
else()
|
||||
message(STATUS "Interprocedural optimization support detected")
|
||||
endif()
|
||||
|
||||
set(DIRECTORY deps/llama.cpp-mainline)
|
||||
include(llama.cpp.cmake)
|
||||
|
||||
set(BUILD_VARIANTS)
|
||||
if (APPLE)
|
||||
list(APPEND BUILD_VARIANTS metal)
|
||||
endif()
|
||||
if (LLMODEL_KOMPUTE)
|
||||
list(APPEND BUILD_VARIANTS kompute kompute-avxonly)
|
||||
else()
|
||||
list(PREPEND BUILD_VARIANTS cpu cpu-avxonly)
|
||||
endif()
|
||||
if (LLMODEL_VULKAN)
|
||||
list(APPEND BUILD_VARIANTS vulkan vulkan-avxonly)
|
||||
endif()
|
||||
if (LLMODEL_CUDA)
|
||||
cmake_minimum_required(VERSION 3.18) # for CMAKE_CUDA_ARCHITECTURES
|
||||
|
||||
# Defaults must be set before enable_language(CUDA).
|
||||
# Keep this in sync with the arch list in ggml/src/CMakeLists.txt (plus 5.0 for non-F16 branch).
|
||||
if (NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
|
||||
# 52 == lowest CUDA 12 standard
|
||||
# 60 == f16 CUDA intrinsics
|
||||
# 61 == integer CUDA intrinsics
|
||||
# 70 == compute capability at which unrolling a loop in mul_mat_q kernels is faster
|
||||
if (GGML_CUDA_F16 OR GGML_CUDA_DMMV_F16)
|
||||
set(CMAKE_CUDA_ARCHITECTURES "60;61;70;75") # needed for f16 CUDA intrinsics
|
||||
else()
|
||||
set(CMAKE_CUDA_ARCHITECTURES "50;52;61;70;75") # lowest CUDA 12 standard + lowest for integer intrinsics
|
||||
#set(CMAKE_CUDA_ARCHITECTURES "OFF") # use this to compile much faster, but only F16 models work
|
||||
endif()
|
||||
endif()
|
||||
message(STATUS "Using CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}")
|
||||
|
||||
include(CheckLanguage)
|
||||
check_language(CUDA)
|
||||
if (NOT CMAKE_CUDA_COMPILER)
|
||||
message(WARNING "CUDA Toolkit not found. To build without CUDA, use -DLLMODEL_CUDA=OFF.")
|
||||
endif()
|
||||
enable_language(CUDA)
|
||||
list(APPEND BUILD_VARIANTS cuda cuda-avxonly)
|
||||
endif()
|
||||
if (LLMODEL_ROCM)
|
||||
enable_language(HIP)
|
||||
list(APPEND BUILD_VARIANTS rocm rocm-avxonly)
|
||||
endif()
|
||||
|
||||
# Go through each build variant
|
||||
foreach(BUILD_VARIANT IN LISTS BUILD_VARIANTS)
|
||||
# Determine flags
|
||||
if (BUILD_VARIANT MATCHES avxonly)
|
||||
set(GPT4ALL_ALLOW_NON_AVX OFF)
|
||||
else()
|
||||
set(GPT4ALL_ALLOW_NON_AVX ON)
|
||||
endif()
|
||||
set(GGML_AVX2 ${GPT4ALL_ALLOW_NON_AVX})
|
||||
set(GGML_F16C ${GPT4ALL_ALLOW_NON_AVX})
|
||||
set(GGML_FMA ${GPT4ALL_ALLOW_NON_AVX})
|
||||
|
||||
set(GGML_METAL OFF)
|
||||
set(GGML_KOMPUTE OFF)
|
||||
set(GGML_VULKAN OFF)
|
||||
set(GGML_CUDA OFF)
|
||||
set(GGML_ROCM OFF)
|
||||
if (BUILD_VARIANT MATCHES metal)
|
||||
set(GGML_METAL ON)
|
||||
elseif (BUILD_VARIANT MATCHES kompute)
|
||||
set(GGML_KOMPUTE ON)
|
||||
elseif (BUILD_VARIANT MATCHES vulkan)
|
||||
set(GGML_VULKAN ON)
|
||||
elseif (BUILD_VARIANT MATCHES cuda)
|
||||
set(GGML_CUDA ON)
|
||||
elseif (BUILD_VARIANT MATCHES rocm)
|
||||
set(GGML_HIPBLAS ON)
|
||||
endif()
|
||||
|
||||
# Include GGML
|
||||
include_ggml(-mainline-${BUILD_VARIANT})
|
||||
|
||||
if (BUILD_VARIANT MATCHES metal)
|
||||
set(GGML_METALLIB "${GGML_METALLIB}" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
# Function for preparing individual implementations
|
||||
function(prepare_target TARGET_NAME BASE_LIB)
|
||||
set(TARGET_NAME ${TARGET_NAME}-${BUILD_VARIANT})
|
||||
message(STATUS "Configuring model implementation target ${TARGET_NAME}")
|
||||
# Link to ggml/llama
|
||||
target_link_libraries(${TARGET_NAME}
|
||||
PRIVATE ${BASE_LIB}-${BUILD_VARIANT})
|
||||
# Let it know about its build variant
|
||||
target_compile_definitions(${TARGET_NAME}
|
||||
PRIVATE GGML_BUILD_VARIANT="${BUILD_VARIANT}")
|
||||
# Enable IPO if possible
|
||||
# FIXME: Doesn't work with msvc reliably. See https://github.com/nomic-ai/gpt4all/issues/841
|
||||
# set_property(TARGET ${TARGET_NAME}
|
||||
# PROPERTY INTERPROCEDURAL_OPTIMIZATION ${IPO_SUPPORTED})
|
||||
endfunction()
|
||||
|
||||
# Add each individual implementations
|
||||
add_library(llamamodel-mainline-${BUILD_VARIANT} SHARED
|
||||
src/llamamodel.cpp src/llmodel_shared.cpp)
|
||||
gpt4all_add_warning_options(llamamodel-mainline-${BUILD_VARIANT})
|
||||
target_compile_definitions(llamamodel-mainline-${BUILD_VARIANT} PRIVATE
|
||||
LLAMA_VERSIONS=>=3 LLAMA_DATE=999999)
|
||||
target_include_directories(llamamodel-mainline-${BUILD_VARIANT} PRIVATE
|
||||
src include/gpt4all-backend
|
||||
)
|
||||
prepare_target(llamamodel-mainline llama-mainline)
|
||||
|
||||
if (NOT PROJECT_IS_TOP_LEVEL AND BUILD_VARIANT STREQUAL cuda)
|
||||
set(CUDAToolkit_BIN_DIR ${CUDAToolkit_BIN_DIR} PARENT_SCOPE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
add_library(llmodel
|
||||
src/dlhandle.cpp
|
||||
src/llmodel.cpp
|
||||
src/llmodel_c.cpp
|
||||
src/llmodel_shared.cpp
|
||||
)
|
||||
gpt4all_add_warning_options(llmodel)
|
||||
target_sources(llmodel PUBLIC
|
||||
FILE_SET public_headers TYPE HEADERS BASE_DIRS include
|
||||
FILES include/gpt4all-backend/llmodel.h
|
||||
include/gpt4all-backend/llmodel_c.h
|
||||
include/gpt4all-backend/sysinfo.h
|
||||
)
|
||||
target_compile_definitions(llmodel PRIVATE LIB_FILE_EXT="${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
target_include_directories(llmodel PRIVATE src include/gpt4all-backend)
|
||||
|
||||
set_target_properties(llmodel PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR})
|
||||
|
||||
set(COMPONENT_NAME_MAIN ${PROJECT_NAME})
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install)
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
include(FetchContent)
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
|
||||
add_subdirectory(date)
|
||||
1
gpt4all-backend/deps/llama.cpp-mainline
Submodule
@@ -1,33 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <fmt/base.h>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QStringView>
|
||||
#include <QUtf8StringView>
|
||||
#include <QVariant>
|
||||
|
||||
#include <string_view>
|
||||
|
||||
|
||||
// fmtlib formatters for QString and QVariant
|
||||
|
||||
#define MAKE_FORMATTER(type, conversion) \
|
||||
template <> \
|
||||
struct fmt::formatter<type, char> : fmt::formatter<std::string_view, char> { \
|
||||
template <typename FmtContext> \
|
||||
FmtContext::iterator format(const type &value, FmtContext &ctx) const \
|
||||
{ \
|
||||
auto valueUtf8 = (conversion); \
|
||||
std::string_view view(valueUtf8.cbegin(), valueUtf8.cend()); \
|
||||
return formatter<std::string_view, char>::format(view, ctx); \
|
||||
} \
|
||||
}
|
||||
|
||||
MAKE_FORMATTER(QLatin1StringView, value );
|
||||
MAKE_FORMATTER(QString, value.toUtf8() );
|
||||
MAKE_FORMATTER(QStringView, value.toUtf8() );
|
||||
MAKE_FORMATTER(QUtf8StringView, value );
|
||||
MAKE_FORMATTER(QVariant, value.toString().toUtf8());
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtTypes>
|
||||
|
||||
|
||||
namespace gpt4all::backend {
|
||||
|
||||
|
||||
struct GenerationParams {
|
||||
uint n_predict;
|
||||
float temperature;
|
||||
float top_p;
|
||||
// int32_t top_k = 40;
|
||||
// float min_p = 0.0f;
|
||||
// int32_t n_batch = 9;
|
||||
// float repeat_penalty = 1.10f;
|
||||
// int32_t repeat_last_n = 64; // last n tokens to penalize
|
||||
// float contextErase = 0.5f; // percent of context to erase if we exceed the context window
|
||||
};
|
||||
|
||||
|
||||
} // namespace gpt4all::backend
|
||||
@@ -1,15 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class QString;
|
||||
namespace boost::json {
|
||||
class value;
|
||||
struct value_from_tag;
|
||||
template <typename T> struct value_to_tag;
|
||||
}
|
||||
|
||||
|
||||
/// Allows QString to be serialized to JSON.
|
||||
void tag_invoke(const boost::json::value_from_tag &, boost::json::value &value, const QString &qstr);
|
||||
|
||||
/// Allows JSON strings to be deserialized as QString.
|
||||
QString tag_invoke(const boost::json::value_to_tag<QString> &, const boost::json::value &value);
|
||||
@@ -1,101 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ollama-types.h"
|
||||
|
||||
#include <QCoro/QCoroTask> // IWYU pragma: keep
|
||||
#include <boost/json.hpp> // IWYU pragma: keep
|
||||
#include <boost/system.hpp> // IWYU pragma: keep
|
||||
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
|
||||
class QNetworkRequest;
|
||||
class QRestReply;
|
||||
|
||||
|
||||
namespace gpt4all::backend {
|
||||
|
||||
|
||||
struct ResponseError {
|
||||
public:
|
||||
struct BadStatus { int code; std::optional<QString> reason; };
|
||||
using ErrorCode = std::variant<
|
||||
QNetworkReply::NetworkError,
|
||||
boost::system::error_code,
|
||||
BadStatus
|
||||
>;
|
||||
|
||||
ResponseError(const QRestReply *reply);
|
||||
ResponseError(const boost::system::system_error &e);
|
||||
|
||||
const ErrorCode &error () const { return m_error; }
|
||||
const QString &errorString() const { return m_errorString; }
|
||||
|
||||
private:
|
||||
ErrorCode m_error;
|
||||
QString m_errorString;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using DataOrRespErr = std::expected<T, ResponseError>;
|
||||
|
||||
class OllamaClient {
|
||||
public:
|
||||
OllamaClient(QUrl baseUrl, QString m_userAgent, QNetworkAccessManager *nam)
|
||||
: m_baseUrl(std::move(baseUrl))
|
||||
, m_userAgent(std::move(m_userAgent))
|
||||
, m_nam(nam)
|
||||
{}
|
||||
|
||||
const QUrl &baseUrl() const { return m_baseUrl; }
|
||||
void getBaseUrl(QUrl value) { m_baseUrl = std::move(value); }
|
||||
|
||||
/// Returns the Ollama server version as a string.
|
||||
auto version() -> QCoro::Task<DataOrRespErr<ollama::VersionResponse>>
|
||||
{ return get<ollama::VersionResponse>(QStringLiteral("version")); }
|
||||
|
||||
/// Lists models that are available locally.
|
||||
auto list() -> QCoro::Task<DataOrRespErr<ollama::ListResponse>>
|
||||
{ return get<ollama::ListResponse>(QStringLiteral("tags")); }
|
||||
|
||||
/// Obtains model information, including details, modelfile, license etc.
|
||||
auto show(const ollama::ShowRequest &req) -> QCoro::Task<DataOrRespErr<ollama::ShowResponse>>
|
||||
{ return post<ollama::ShowResponse>(QStringLiteral("show"), req); }
|
||||
|
||||
private:
|
||||
QNetworkRequest makeRequest(const QString &path) const;
|
||||
|
||||
auto processResponse(std::unique_ptr<QNetworkReply> reply) -> QCoro::Task<DataOrRespErr<boost::json::value>>;
|
||||
|
||||
template <typename Resp>
|
||||
auto get(QString path) -> QCoro::Task<DataOrRespErr<Resp>>;
|
||||
template <typename Resp, typename Req>
|
||||
auto post(QString path, Req const &body) -> QCoro::Task<DataOrRespErr<Resp>>;
|
||||
|
||||
auto getJson(QString path) -> QCoro::Task<DataOrRespErr<boost::json::value>>;
|
||||
auto postJson(const QString &path, const boost::json::value &body)
|
||||
-> QCoro::Task<DataOrRespErr<boost::json::value>>;
|
||||
|
||||
private:
|
||||
QUrl m_baseUrl;
|
||||
QString m_userAgent;
|
||||
QNetworkAccessManager *m_nam;
|
||||
boost::json::stream_parser m_parser;
|
||||
};
|
||||
|
||||
extern template auto OllamaClient::get(QString) -> QCoro::Task<DataOrRespErr<ollama::VersionResponse>>;
|
||||
extern template auto OllamaClient::get(QString) -> QCoro::Task<DataOrRespErr<ollama::ListResponse>>;
|
||||
|
||||
extern template auto OllamaClient::post(QString, const ollama::ShowRequest &)
|
||||
-> QCoro::Task<DataOrRespErr<ollama::ShowResponse>>;
|
||||
|
||||
|
||||
} // namespace gpt4all::backend
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace gpt4all::backend {
|
||||
|
||||
|
||||
class OllamaClient;
|
||||
|
||||
class OllamaModel {
|
||||
OllamaClient *client;
|
||||
};
|
||||
|
||||
|
||||
} // namespace gpt4all::backend
|
||||
@@ -1,128 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "json-helpers.h" // IWYU pragma: keep
|
||||
|
||||
#include <boost/describe/class.hpp>
|
||||
#include <boost/json.hpp> // IWYU pragma: keep
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <QtTypes>
|
||||
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace gpt4all::backend::ollama {
|
||||
|
||||
|
||||
//
|
||||
// basic types
|
||||
//
|
||||
|
||||
struct Time : std::chrono::sys_time<std::chrono::nanoseconds> {};
|
||||
|
||||
void tag_invoke(const boost::json::value_from_tag &, boost::json::value &value, Time time);
|
||||
Time tag_invoke(const boost::json::value_to_tag<Time> &, const boost::json::value &value);
|
||||
|
||||
/// ImageData represents the raw binary data of an image file.
|
||||
struct ImageData : QByteArray {};
|
||||
|
||||
void tag_invoke(const boost::json::value_from_tag &, boost::json::value &value, const ImageData &image);
|
||||
ImageData tag_invoke(const boost::json::value_to_tag<ImageData> &, const boost::json::value &value);
|
||||
|
||||
struct ModelDetails {
|
||||
QString parent_model;
|
||||
QString format;
|
||||
QString family;
|
||||
std::vector<QString> families;
|
||||
QString parameter_size;
|
||||
QString quantization_level;
|
||||
};
|
||||
BOOST_DESCRIBE_STRUCT(ModelDetails, (), (parent_model, format, family, families, parameter_size, quantization_level))
|
||||
|
||||
/// ListModelResponse is a single model description in ListResponse.
|
||||
struct ListModelResponse {
|
||||
QString name;
|
||||
QString model;
|
||||
Time modified_at;
|
||||
qint64 size; /// Size of the model on disk.
|
||||
QString digest;
|
||||
std::optional<ModelDetails> details;
|
||||
};
|
||||
BOOST_DESCRIBE_STRUCT(ListModelResponse, (), (name, model, modified_at, size, digest, details))
|
||||
|
||||
using ToolCallFunctionArguments = boost::json::object;
|
||||
|
||||
struct ToolCallFunction {
|
||||
std::optional<int> index;
|
||||
QString name;
|
||||
ToolCallFunctionArguments arguments;
|
||||
};
|
||||
BOOST_DESCRIBE_STRUCT(ToolCallFunction, (), (index, name, arguments))
|
||||
|
||||
struct ToolCall {
|
||||
ToolCallFunction function;
|
||||
};
|
||||
BOOST_DESCRIBE_STRUCT(ToolCall, (), (function))
|
||||
|
||||
/// Message is a single message in a chat sequence. The message contains the
|
||||
/// role ("system", "user", or "assistant"), the content and an optional list
|
||||
/// of images.
|
||||
struct Message {
|
||||
QString role;
|
||||
QString content;
|
||||
std::optional<std::vector<ImageData>> images;
|
||||
std::optional<std::vector<ToolCall>> tool_calls;
|
||||
};
|
||||
BOOST_DESCRIBE_STRUCT(Message, (), (role, content, images, tool_calls))
|
||||
|
||||
//
|
||||
// request types
|
||||
//
|
||||
|
||||
/// ShowRequest is the request passed to OllamaClient::show().
|
||||
struct ShowRequest {
|
||||
QString model;
|
||||
std::optional<QString> system {};
|
||||
std::optional<bool> verbose {};
|
||||
std::optional<boost::json::object> options {};
|
||||
};
|
||||
BOOST_DESCRIBE_STRUCT(ShowRequest, (), (model, system, verbose, options))
|
||||
|
||||
//
|
||||
// response types
|
||||
//
|
||||
|
||||
/// VersionRepsonse is the response from OllamaClient::version().
|
||||
struct VersionResponse {
|
||||
QString version; /// The version of the Ollama server.
|
||||
};
|
||||
BOOST_DESCRIBE_STRUCT(VersionResponse, (), (version))
|
||||
|
||||
/// ShowResponse is the response from OllamaClient::show().
|
||||
struct ShowResponse {
|
||||
std::optional<QString> license;
|
||||
std::optional<QString> modelfile; /// The modelfile associated with the model.
|
||||
std::optional<QString> parameters;
|
||||
std::optional<QString> template_; /// The prompt template for the model.
|
||||
std::optional<QString> system; /// The system prompt for the model.
|
||||
std::optional<ModelDetails> details;
|
||||
std::optional<std::vector<Message>> messages; /// The default messages for the model.
|
||||
std::optional<boost::json::object> model_info;
|
||||
std::optional<boost::json::object> projector_info;
|
||||
std::optional<Time> modified_at;
|
||||
};
|
||||
|
||||
void tag_invoke(const boost::json::value_from_tag &, boost::json::value &value, const ShowResponse &resp);
|
||||
ShowResponse tag_invoke(const boost::json::value_to_tag<ShowResponse> &, const boost::json::value &value);
|
||||
|
||||
/// ListResponse is the response from OllamaClient::list().
|
||||
struct ListResponse {
|
||||
std::vector<ListModelResponse> models; /// List of available models.
|
||||
};
|
||||
BOOST_DESCRIBE_STRUCT(ListResponse, (), (models))
|
||||
|
||||
|
||||
} // namespace gpt4all::backend::ollama
|
||||
@@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class QRestReply;
|
||||
class QString;
|
||||
|
||||
|
||||
namespace gpt4all::backend {
|
||||
|
||||
|
||||
QString restErrorString(const QRestReply &reply);
|
||||
|
||||
|
||||
} // namespace gpt4all::backend
|
||||
@@ -1,31 +0,0 @@
|
||||
set(TARGET gpt4all-backend)
|
||||
|
||||
add_library(${TARGET} STATIC
|
||||
json-helpers.cpp
|
||||
ollama-client.cpp
|
||||
ollama-types.cpp
|
||||
qt-json-stream.cpp
|
||||
rest.cpp
|
||||
)
|
||||
target_compile_features(${TARGET} PUBLIC cxx_std_23)
|
||||
gpt4all_add_warning_options(${TARGET})
|
||||
target_include_directories(${TARGET} PRIVATE
|
||||
.
|
||||
../include/gpt4all-backend
|
||||
)
|
||||
target_link_libraries(${TARGET} PUBLIC
|
||||
Boost::describe
|
||||
QCoro6::Coro
|
||||
Qt6::Core
|
||||
Qt6::Network
|
||||
)
|
||||
target_link_libraries(${TARGET} PRIVATE
|
||||
QCoro6::Network
|
||||
date::date
|
||||
fmt::fmt
|
||||
)
|
||||
|
||||
# link Boost::json as -isystem to suppress -Wundef
|
||||
get_target_property(LIB_INCLUDE_DIRS Boost::json INTERFACE_INCLUDE_DIRECTORIES)
|
||||
target_include_directories(${TARGET} SYSTEM PUBLIC ${LIB_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET} PUBLIC Boost::json)
|
||||
@@ -1,21 +0,0 @@
|
||||
#include "json-helpers.h"
|
||||
|
||||
#include <boost/json.hpp> // IWYU pragma: keep
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
|
||||
namespace json = boost::json;
|
||||
|
||||
|
||||
void tag_invoke(const boost::json::value_from_tag &, boost::json::value &value, const QString &qstr)
|
||||
{
|
||||
auto utf8 = qstr.toUtf8();
|
||||
value = json::value_from(json::string_view(utf8.data(), utf8.size()));
|
||||
}
|
||||
|
||||
QString tag_invoke(const boost::json::value_to_tag<QString> &, const boost::json::value &value)
|
||||
{
|
||||
auto &s = value.as_string();
|
||||
return QString::fromUtf8(s.data(), s.size());
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
#include "ollama-client.h"
|
||||
|
||||
#include "json-helpers.h" // IWYU pragma: keep
|
||||
#include "qt-json-stream.h"
|
||||
#include "rest.h"
|
||||
|
||||
#include <QCoro/QCoroIODevice> // IWYU pragma: keep
|
||||
#include <QCoro/QCoroNetworkReply> // IWYU pragma: keep
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QNetworkRequest>
|
||||
#include <QRestReply>
|
||||
#include <QVariant>
|
||||
#include <QtAssert>
|
||||
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
using namespace gpt4all::backend::ollama;
|
||||
namespace json = boost::json;
|
||||
|
||||
|
||||
namespace gpt4all::backend {
|
||||
|
||||
|
||||
ResponseError::ResponseError(const QRestReply *reply)
|
||||
{
|
||||
if (reply->hasError()) {
|
||||
m_error = reply->networkReply()->error();
|
||||
} else if (!reply->isHttpStatusSuccess()) {
|
||||
auto reason = reply->networkReply()->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
|
||||
m_error = BadStatus(reply->httpStatus(), reason.isEmpty() ? std::nullopt : std::optional(reason));
|
||||
} else
|
||||
Q_UNREACHABLE();
|
||||
|
||||
m_errorString = restErrorString(*reply);
|
||||
}
|
||||
|
||||
ResponseError::ResponseError(const boost::system::system_error &e)
|
||||
: m_error(e.code())
|
||||
, m_errorString(QString::fromUtf8(e.what()))
|
||||
{
|
||||
Q_ASSERT(e.code());
|
||||
}
|
||||
|
||||
QNetworkRequest OllamaClient::makeRequest(const QString &path) const
|
||||
{
|
||||
QNetworkRequest req(m_baseUrl.resolved(QUrl(path)));
|
||||
req.setHeader(QNetworkRequest::UserAgentHeader, m_userAgent);
|
||||
return req;
|
||||
}
|
||||
|
||||
auto OllamaClient::processResponse(std::unique_ptr<QNetworkReply> reply) -> QCoro::Task<DataOrRespErr<json::value>>
|
||||
{
|
||||
QRestReply restReply(reply.get());
|
||||
if (reply->error())
|
||||
co_return std::unexpected(&restReply);
|
||||
|
||||
auto coroReply = qCoro(*reply);
|
||||
for (;;) {
|
||||
auto chunk = co_await coroReply.readAll();
|
||||
if (!restReply.isSuccess())
|
||||
co_return std::unexpected(&restReply);
|
||||
if (chunk.isEmpty()) {
|
||||
Q_ASSERT(reply->atEnd());
|
||||
break;
|
||||
}
|
||||
m_parser.write(chunk.data(), chunk.size());
|
||||
}
|
||||
|
||||
m_parser.finish();
|
||||
co_return m_parser.release();
|
||||
}
|
||||
|
||||
template <typename Resp>
|
||||
auto OllamaClient::get(QString path) -> QCoro::Task<DataOrRespErr<Resp>>
|
||||
{
|
||||
// get() should not throw exceptions
|
||||
try {
|
||||
auto value = co_await getJson(path);
|
||||
if (value)
|
||||
co_return json::value_to<Resp>(*value);
|
||||
co_return std::unexpected(value.error());
|
||||
} catch (const boost::system::system_error &e) {
|
||||
co_return std::unexpected(e);
|
||||
}
|
||||
}
|
||||
|
||||
template auto OllamaClient::get(QString) -> QCoro::Task<DataOrRespErr<VersionResponse>>;
|
||||
template auto OllamaClient::get(QString) -> QCoro::Task<DataOrRespErr<ListResponse>>;
|
||||
|
||||
template <typename Resp, typename Req>
|
||||
auto OllamaClient::post(QString path, const Req &body) -> QCoro::Task<DataOrRespErr<Resp>>
|
||||
{
|
||||
// post() should not throw exceptions
|
||||
try {
|
||||
auto reqJson = json::value_from(body);
|
||||
auto value = co_await postJson(path, reqJson);
|
||||
if (value)
|
||||
co_return json::value_to<Resp>(*value);
|
||||
co_return std::unexpected(value.error());
|
||||
} catch (const boost::system::system_error &e) {
|
||||
co_return std::unexpected(e);
|
||||
}
|
||||
}
|
||||
|
||||
template auto OllamaClient::post(QString, const ShowRequest &) -> QCoro::Task<DataOrRespErr<ShowResponse>>;
|
||||
|
||||
auto OllamaClient::getJson(QString path) -> QCoro::Task<DataOrRespErr<json::value>>
|
||||
{
|
||||
std::unique_ptr<QNetworkReply> reply(m_nam->get(makeRequest(path)));
|
||||
return processResponse(std::move(reply));
|
||||
}
|
||||
|
||||
auto OllamaClient::postJson(const QString &path, const json::value &body) -> QCoro::Task<DataOrRespErr<json::value>>
|
||||
{
|
||||
JsonStreamDevice stream(&body);
|
||||
auto req = makeRequest(path);
|
||||
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"_ba);
|
||||
std::unique_ptr<QNetworkReply> reply(m_nam->post(req, &stream));
|
||||
co_return co_await processResponse(std::move(reply));
|
||||
}
|
||||
|
||||
|
||||
} // namespace gpt4all::backend
|
||||
@@ -1,99 +0,0 @@
|
||||
#include "ollama-types.h"
|
||||
|
||||
#include "json-helpers.h"
|
||||
|
||||
#include <fmt/chrono.h> // IWYU pragma: keep
|
||||
#include <fmt/format.h>
|
||||
#include <date/date.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <system_error>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace json = boost::json;
|
||||
|
||||
|
||||
template <typename T>
|
||||
static T get_optional(const json::object &o, json::string_view key)
|
||||
{
|
||||
if (auto *p = o.if_contains(key))
|
||||
return value_to<typename T::value_type>(*p);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
namespace gpt4all::backend::ollama {
|
||||
|
||||
|
||||
void tag_invoke(const json::value_from_tag &, json::value &value, Time time)
|
||||
{
|
||||
value = json::value_from(fmt::format(
|
||||
"{:%FT%T}Z",
|
||||
static_cast<const std::chrono::sys_time<std::chrono::nanoseconds> &>(time)
|
||||
));
|
||||
}
|
||||
|
||||
Time tag_invoke(const json::value_to_tag<Time> &, const json::value &value)
|
||||
{
|
||||
namespace sys = boost::system;
|
||||
|
||||
Time time;
|
||||
std::istringstream iss(json::string_view(value.as_string()));
|
||||
iss >> date::parse("%FT%T%Ez", time);
|
||||
if (!iss && !iss.eof())
|
||||
throw sys::system_error(std::make_error_code(std::errc::invalid_argument), __func__);
|
||||
return time;
|
||||
}
|
||||
|
||||
void tag_invoke(const json::value_from_tag &, json::value &value, const ImageData &image)
|
||||
{
|
||||
auto base64 = image.toBase64();
|
||||
value = json::value_from(json::string_view(base64.data(), base64.size()));
|
||||
}
|
||||
|
||||
ImageData tag_invoke(const json::value_to_tag<ImageData> &, const json::value &value)
|
||||
{
|
||||
auto &str = value.as_string();
|
||||
return ImageData(QByteArray::fromBase64(QByteArray::fromRawData(str.data(), str.size())));
|
||||
}
|
||||
|
||||
void tag_invoke(const json::value_from_tag &, json::value &value, const ShowResponse &resp)
|
||||
{
|
||||
auto &o = value.emplace_object();
|
||||
|
||||
auto maybe_add = [&o](json::string_view key, auto &v) { if (v) o[key] = json::value_from(*v); };
|
||||
maybe_add("license", resp.license );
|
||||
maybe_add("modelfile", resp.modelfile );
|
||||
maybe_add("parameters", resp.parameters );
|
||||
maybe_add("template", resp.template_ );
|
||||
maybe_add("system", resp.system );
|
||||
maybe_add("details", resp.details );
|
||||
maybe_add("messages", resp.messages );
|
||||
maybe_add("model_info", resp.model_info );
|
||||
maybe_add("projector_info", resp.projector_info);
|
||||
maybe_add("modified_at", resp.modified_at );
|
||||
}
|
||||
|
||||
ShowResponse tag_invoke(const json::value_to_tag<ShowResponse> &, const json::value &value)
|
||||
{
|
||||
auto &o = value.as_object();
|
||||
return {
|
||||
#define T(name) std::remove_reference_t<decltype(std::declval<ShowResponse>().name)>
|
||||
.license = get_optional<T(license )>(o, "license" ),
|
||||
.modelfile = get_optional<T(modelfile )>(o, "modelfile" ),
|
||||
.parameters = get_optional<T(parameters )>(o, "parameters" ),
|
||||
.template_ = get_optional<T(template_ )>(o, "template" ), // :(
|
||||
.system = get_optional<T(system )>(o, "system" ),
|
||||
.details = get_optional<T(details )>(o, "details" ),
|
||||
.messages = get_optional<T(messages )>(o, "messages" ),
|
||||
.model_info = get_optional<T(model_info )>(o, "model_info" ),
|
||||
.projector_info = get_optional<T(projector_info)>(o, "projector_info"),
|
||||
.modified_at = get_optional<T(modified_at )>(o, "modified_at" ),
|
||||
#undef T
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
} // namespace gpt4all::backend::ollama
|
||||
@@ -1,36 +0,0 @@
|
||||
#include "qt-json-stream.h"
|
||||
|
||||
#include <QtPreprocessorSupport>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace json = boost::json;
|
||||
|
||||
|
||||
namespace gpt4all::backend {
|
||||
|
||||
|
||||
JsonStreamDevice::JsonStreamDevice(const json::value *jv, QObject *parent)
|
||||
: QIODevice(parent)
|
||||
{
|
||||
m_sr.reset(jv);
|
||||
open(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
qint64 JsonStreamDevice::readData(char *data, qint64 maxSize)
|
||||
{
|
||||
if (m_sr.done()) return -1; // EOF
|
||||
auto chunk = m_sr.read(data, size_t(maxSize));
|
||||
return qint64(chunk.size());
|
||||
}
|
||||
|
||||
qint64 JsonStreamDevice::writeData(const char *data, qint64 maxSize)
|
||||
{
|
||||
Q_UNUSED(data)
|
||||
Q_UNUSED(maxSize)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
} // namespace gpt4all::backend
|
||||
@@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <boost/json.hpp> // IWYU pragma: keep
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QtTypes>
|
||||
|
||||
class QObject;
|
||||
|
||||
|
||||
namespace gpt4all::backend {
|
||||
|
||||
|
||||
class JsonStreamDevice : public QIODevice
|
||||
{
|
||||
public:
|
||||
explicit JsonStreamDevice(const boost::json::value *jv, QObject *parent = nullptr);
|
||||
|
||||
bool isSequential() const override { return true; }
|
||||
|
||||
protected:
|
||||
qint64 readData(char *data, qint64 maxSize) override;
|
||||
qint64 writeData(const char *data, qint64 maxSize) override;
|
||||
|
||||
private:
|
||||
boost::json::serializer m_sr;
|
||||
};
|
||||
|
||||
|
||||
} // namespace gpt4all::backend
|
||||
@@ -1,34 +0,0 @@
|
||||
#include "rest.h"
|
||||
|
||||
#include <QNetworkReply>
|
||||
#include <QRestReply>
|
||||
#include <QString>
|
||||
|
||||
using namespace Qt::Literals::StringLiterals;
|
||||
|
||||
|
||||
namespace gpt4all::backend {
|
||||
|
||||
|
||||
QString restErrorString(const QRestReply &reply)
|
||||
{
|
||||
auto *nr = reply.networkReply();
|
||||
if (reply.hasError())
|
||||
return nr->errorString();
|
||||
|
||||
if (!reply.isHttpStatusSuccess()) {
|
||||
auto code = reply.httpStatus();
|
||||
auto reason = nr->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
|
||||
return u"HTTP %1%2%3 for URL \"%4\""_s.arg(
|
||||
QString::number(code),
|
||||
reason.isEmpty() ? QString() : u" "_s,
|
||||
reason,
|
||||
nr->request().url().toString()
|
||||
);
|
||||
}
|
||||
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
} // namespace gpt4all::backend
|
||||
21
gpt4all-bindings/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# GPT4All Language Bindings
|
||||
These are the language bindings for the GPT4All backend. They provide functionality to load GPT4All models (and other llama.cpp models), generate text, and (in the case of the Python bindings) embed text as a vector representation.
|
||||
|
||||
See their respective folders for language-specific documentation.
|
||||
|
||||
### Languages
|
||||
- [Python](https://github.com/nomic-ai/gpt4all/tree/main/gpt4all-bindings/python) (Nomic official, maintained by [@cebtenzzre](https://github.com/cebtenzzre))
|
||||
- [Node.js/Typescript](https://github.com/nomic-ai/gpt4all/tree/main/gpt4all-bindings/typescript) (community, maintained by [@jacoobes](https://github.com/jacoobes) and [@iimez](https://github.com/iimez))
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<details><summary><b>Archived Bindings</b></summary>
|
||||
<br/>
|
||||
|
||||
The following bindings have been removed from this repository due to lack of maintenance. If adopted, they can be brought back—feel free to message a developer on Dicsord if you are interested in maintaining one of them. Below are links to their last available version (not necessarily the last working version).
|
||||
- C#: [41c9013f](https://github.com/nomic-ai/gpt4all/tree/41c9013fa46a194b3e4fee6ced1b9d1b65e177ac/gpt4all-bindings/csharp)
|
||||
- Java: [41c9013f](https://github.com/nomic-ai/gpt4all/tree/41c9013fa46a194b3e4fee6ced1b9d1b65e177ac/gpt4all-bindings/java)
|
||||
- Go: [41c9013f](https://github.com/nomic-ai/gpt4all/tree/41c9013fa46a194b3e4fee6ced1b9d1b65e177ac/gpt4all-bindings/golang)
|
||||
|
||||
</details>
|
||||
43
gpt4all-bindings/cli/README.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# GPT4All Command-Line Interface (CLI)
|
||||
|
||||
GPT4All on the command-line.
|
||||
|
||||
More details on the [wiki](https://github.com/nomic-ai/gpt4all/wiki/Python-CLI).
|
||||
|
||||
## Quickstart
|
||||
|
||||
The CLI is based on the `gpt4all` Python bindings and the `typer` package.
|
||||
|
||||
The following shows one way to get started with the CLI, the documentation has more information.
|
||||
Typically, you will want to replace `python` with `python3` on _Unix-like_ systems and `py -3` on
|
||||
_Windows_. Also, it's assumed you have all the necessary Python components already installed.
|
||||
|
||||
The CLI is a self-contained Python script named [app.py] ([download][app.py-download]). As long as
|
||||
its package dependencies are present, you can download and run it from wherever you like.
|
||||
|
||||
[app.py]: https://github.com/nomic-ai/gpt4all/blob/main/gpt4all-bindings/cli/app.py
|
||||
[app.py-download]: https://raw.githubusercontent.com/nomic-ai/gpt4all/main/gpt4all-bindings/cli/app.py
|
||||
|
||||
```shell
|
||||
# optional but recommended: create and use a virtual environment
|
||||
python -m venv gpt4all-cli
|
||||
```
|
||||
_Windows_ and _Unix-like_ systems differ slightly in how you activate a _virtual environment_:
|
||||
- _Unix-like_, typically: `. gpt4all-cli/bin/activate`
|
||||
- _Windows_: `gpt4all-cli\Scripts\activate`
|
||||
|
||||
Then:
|
||||
```shell
|
||||
# pip-install the necessary packages; omit '--user' if using a virtual environment
|
||||
python -m pip install --user --upgrade gpt4all typer
|
||||
# run the CLI
|
||||
python app.py repl
|
||||
```
|
||||
By default, it will automatically download the `Mistral Instruct` model to `.cache/gpt4all/` in your
|
||||
user directory, if necessary.
|
||||
|
||||
If you have already saved a model beforehand, specify its path with the `-m`/`--model` argument,
|
||||
for example:
|
||||
```shell
|
||||
python app.py repl --model /home/user/my-gpt4all-models/mistral-7b-instruct-v0.1.Q4_0.gguf
|
||||
```
|
||||
184
gpt4all-bindings/cli/app.py
Executable file
@@ -0,0 +1,184 @@
|
||||
#!/usr/bin/env python3
|
||||
"""GPT4All CLI
|
||||
|
||||
The GPT4All CLI is a self-contained script based on the `gpt4all` and `typer` packages. It offers a
|
||||
REPL to communicate with a language model similar to the chat GUI application, but more basic.
|
||||
"""
|
||||
|
||||
import importlib.metadata
|
||||
import io
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
from typing_extensions import Annotated
|
||||
|
||||
import typer
|
||||
from gpt4all import GPT4All
|
||||
|
||||
|
||||
MESSAGES = [
|
||||
{"role": "system", "content": "You are a helpful assistant."},
|
||||
{"role": "user", "content": "Hello there."},
|
||||
{"role": "assistant", "content": "Hi, how can I help you?"},
|
||||
]
|
||||
|
||||
SPECIAL_COMMANDS = {
|
||||
"/reset": lambda messages: messages.clear(),
|
||||
"/exit": lambda _: sys.exit(),
|
||||
"/clear": lambda _: print("\n" * 100),
|
||||
"/help": lambda _: print("Special commands: /reset, /exit, /help and /clear"),
|
||||
}
|
||||
|
||||
VersionInfo = namedtuple('VersionInfo', ['major', 'minor', 'micro'])
|
||||
VERSION_INFO = VersionInfo(1, 0, 2)
|
||||
VERSION = '.'.join(map(str, VERSION_INFO)) # convert to string form, like: '1.2.3'
|
||||
|
||||
CLI_START_MESSAGE = f"""
|
||||
|
||||
██████ ██████ ████████ ██ ██ █████ ██ ██
|
||||
██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
██ ███ ██████ ██ ███████ ███████ ██ ██
|
||||
██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
██████ ██ ██ ██ ██ ██ ███████ ███████
|
||||
|
||||
|
||||
Welcome to the GPT4All CLI! Version {VERSION}
|
||||
Type /help for special commands.
|
||||
|
||||
"""
|
||||
|
||||
# create typer app
|
||||
app = typer.Typer()
|
||||
|
||||
@app.command()
|
||||
def repl(
|
||||
model: Annotated[
|
||||
str,
|
||||
typer.Option("--model", "-m", help="Model to use for chatbot"),
|
||||
] = "mistral-7b-instruct-v0.1.Q4_0.gguf",
|
||||
n_threads: Annotated[
|
||||
int,
|
||||
typer.Option("--n-threads", "-t", help="Number of threads to use for chatbot"),
|
||||
] = None,
|
||||
device: Annotated[
|
||||
str,
|
||||
typer.Option("--device", "-d", help="Device to use for chatbot, e.g. gpu, amd, nvidia, intel. Defaults to CPU."),
|
||||
] = None,
|
||||
):
|
||||
"""The CLI read-eval-print loop."""
|
||||
gpt4all_instance = GPT4All(model, device=device)
|
||||
|
||||
# if threads are passed, set them
|
||||
if n_threads is not None:
|
||||
num_threads = gpt4all_instance.model.thread_count()
|
||||
print(f"\nAdjusted: {num_threads} →", end="")
|
||||
|
||||
# set number of threads
|
||||
gpt4all_instance.model.set_thread_count(n_threads)
|
||||
|
||||
num_threads = gpt4all_instance.model.thread_count()
|
||||
print(f" {num_threads} threads", end="", flush=True)
|
||||
else:
|
||||
print(f"\nUsing {gpt4all_instance.model.thread_count()} threads", end="")
|
||||
|
||||
print(CLI_START_MESSAGE)
|
||||
|
||||
use_new_loop = False
|
||||
try:
|
||||
version = importlib.metadata.version('gpt4all')
|
||||
version_major = int(version.split('.')[0])
|
||||
if version_major >= 1:
|
||||
use_new_loop = True
|
||||
except:
|
||||
pass # fall back to old loop
|
||||
if use_new_loop:
|
||||
_new_loop(gpt4all_instance)
|
||||
else:
|
||||
_old_loop(gpt4all_instance)
|
||||
|
||||
|
||||
def _old_loop(gpt4all_instance):
|
||||
while True:
|
||||
message = input(" ⇢ ")
|
||||
|
||||
# Check if special command and take action
|
||||
if message in SPECIAL_COMMANDS:
|
||||
SPECIAL_COMMANDS[message](MESSAGES)
|
||||
continue
|
||||
|
||||
# if regular message, append to messages
|
||||
MESSAGES.append({"role": "user", "content": message})
|
||||
|
||||
# execute chat completion and ignore the full response since
|
||||
# we are outputting it incrementally
|
||||
full_response = gpt4all_instance.chat_completion(
|
||||
MESSAGES,
|
||||
# preferential kwargs for chat ux
|
||||
n_past=0,
|
||||
n_predict=200,
|
||||
top_k=40,
|
||||
top_p=0.9,
|
||||
min_p=0.0,
|
||||
temp=0.9,
|
||||
n_batch=9,
|
||||
repeat_penalty=1.1,
|
||||
repeat_last_n=64,
|
||||
context_erase=0.0,
|
||||
# required kwargs for cli ux (incremental response)
|
||||
verbose=False,
|
||||
streaming=True,
|
||||
)
|
||||
# record assistant's response to messages
|
||||
MESSAGES.append(full_response.get("choices")[0].get("message"))
|
||||
print() # newline before next prompt
|
||||
|
||||
|
||||
def _new_loop(gpt4all_instance):
|
||||
with gpt4all_instance.chat_session():
|
||||
while True:
|
||||
message = input(" ⇢ ")
|
||||
|
||||
# Check if special command and take action
|
||||
if message in SPECIAL_COMMANDS:
|
||||
SPECIAL_COMMANDS[message](MESSAGES)
|
||||
continue
|
||||
|
||||
# if regular message, append to messages
|
||||
MESSAGES.append({"role": "user", "content": message})
|
||||
|
||||
# execute chat completion and ignore the full response since
|
||||
# we are outputting it incrementally
|
||||
response_generator = gpt4all_instance.generate(
|
||||
message,
|
||||
# preferential kwargs for chat ux
|
||||
max_tokens=200,
|
||||
temp=0.9,
|
||||
top_k=40,
|
||||
top_p=0.9,
|
||||
min_p=0.0,
|
||||
repeat_penalty=1.1,
|
||||
repeat_last_n=64,
|
||||
n_batch=9,
|
||||
# required kwargs for cli ux (incremental response)
|
||||
streaming=True,
|
||||
)
|
||||
response = io.StringIO()
|
||||
for token in response_generator:
|
||||
print(token, end='', flush=True)
|
||||
response.write(token)
|
||||
|
||||
# record assistant's response to messages
|
||||
response_message = {'role': 'assistant', 'content': response.getvalue()}
|
||||
response.close()
|
||||
gpt4all_instance.current_chat_session.append(response_message)
|
||||
MESSAGES.append(response_message)
|
||||
print() # newline before next prompt
|
||||
|
||||
|
||||
@app.command()
|
||||
def version():
|
||||
"""The CLI version command."""
|
||||
print(f"gpt4all-cli v{VERSION}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app()
|
||||
25
gpt4all-bindings/cli/developer_notes.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Developing the CLI
|
||||
## Documentation
|
||||
Documentation can be found in three places:
|
||||
- `app.py` docstrings & comments
|
||||
- a Readme: `gpt4all-bindings/cli/README.md`
|
||||
- the actual CLI documentation: `gpt4all-bindings/python/docs/gpt4all_cli.md`
|
||||
|
||||
The _docstrings_ are meant for programmatic use. Since the CLI is primarily geared towards users and
|
||||
not to build on top, they're kept terse.
|
||||
|
||||
The _Readme_ is mostly meant for users and includes:
|
||||
- a link to the _CLI documentation_ (on the [website])
|
||||
- a Quickstart section with some guidance on how to get started with a sane setup
|
||||
|
||||
The _CLI documentation_ and other documentation are located in the above mentioned `docs/` folder.
|
||||
They're in Markdown format and built for the [website]. Of the three, they should be the most
|
||||
detailed.
|
||||
|
||||
[website]: https://docs.gpt4all.io/gpt4all_cli.html
|
||||
|
||||
|
||||
## Versioning
|
||||
The version number should now follow the `gpt4all` PyPI package, so compatibility is more clear.
|
||||
|
||||
The one place to change it is the `namedtuple` called `VERSION_INFO`.
|
||||
164
gpt4all-bindings/python/.gitignore
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
|
||||
# Cython
|
||||
/*.c
|
||||
*DO_NOT_MODIFY/
|
||||
7
gpt4all-bindings/python/.isort.cfg
Normal file
@@ -0,0 +1,7 @@
|
||||
[settings]
|
||||
known_third_party=geopy,nltk,np,numpy,pandas,pysbd,fire,torch
|
||||
|
||||
line_length=120
|
||||
include_trailing_comma=True
|
||||
multi_line_output=3
|
||||
use_parentheses=True
|
||||
75
gpt4all-bindings/python/CHANGELOG.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- Warn on Windows if the Microsoft Visual C++ runtime libraries are not found ([#2920](https://github.com/nomic-ai/gpt4all/pull/2920))
|
||||
- Basic cache for faster prefill when the input shares a prefix with previous context ([#3073](https://github.com/nomic-ai/gpt4all/pull/3073))
|
||||
- Add ability to modify or replace the history of an active chat session ([#3147](https://github.com/nomic-ai/gpt4all/pull/3147))
|
||||
|
||||
### Changed
|
||||
- Rebase llama.cpp on latest upstream as of September 26th ([#2998](https://github.com/nomic-ai/gpt4all/pull/2998))
|
||||
- Change the error message when a message is too long ([#3004](https://github.com/nomic-ai/gpt4all/pull/3004))
|
||||
- Fix CalledProcessError on Intel Macs since v2.8.0 ([#3045](https://github.com/nomic-ai/gpt4all/pull/3045))
|
||||
- Use Jinja for chat templates instead of per-message QString.arg-style templates ([#3147](https://github.com/nomic-ai/gpt4all/pull/3147))
|
||||
|
||||
## [2.8.2] - 2024-08-14
|
||||
|
||||
### Fixed
|
||||
- Fixed incompatibility with Python 3.8 since v2.7.0 and Python <=3.11 since v2.8.1 ([#2871](https://github.com/nomic-ai/gpt4all/pull/2871))
|
||||
|
||||
## [2.8.1] - 2024-08-13
|
||||
|
||||
### Added
|
||||
- Use greedy sampling when temperature is set to zero ([#2854](https://github.com/nomic-ai/gpt4all/pull/2854))
|
||||
|
||||
### Changed
|
||||
- Search for pip-installed CUDA 11 as well as CUDA 12 ([#2802](https://github.com/nomic-ai/gpt4all/pull/2802))
|
||||
- Stop shipping CUBINs to reduce wheel size ([#2802](https://github.com/nomic-ai/gpt4all/pull/2802))
|
||||
- Use llama\_kv\_cache ops to shift context faster ([#2781](https://github.com/nomic-ai/gpt4all/pull/2781))
|
||||
- Don't stop generating at end of context ([#2781](https://github.com/nomic-ai/gpt4all/pull/2781))
|
||||
|
||||
### Fixed
|
||||
- Make reverse prompt detection work more reliably and prevent it from breaking output ([#2781](https://github.com/nomic-ai/gpt4all/pull/2781))
|
||||
- Explicitly target macOS 12.6 in CI to fix Metal compatibility on older macOS ([#2849](https://github.com/nomic-ai/gpt4all/pull/2849))
|
||||
- Do not initialize Vulkan driver when only using CPU ([#2843](https://github.com/nomic-ai/gpt4all/pull/2843))
|
||||
- Fix a segfault on exit when using CPU mode on Linux with NVIDIA and EGL ([#2843](https://github.com/nomic-ai/gpt4all/pull/2843))
|
||||
|
||||
## [2.8.0] - 2024-08-05
|
||||
|
||||
### Added
|
||||
- Support GPT-NeoX, Gemma 2, OpenELM, ChatGLM, and Jais architectures (all with Vulkan support) ([#2694](https://github.com/nomic-ai/gpt4all/pull/2694))
|
||||
- Enable Vulkan support for StarCoder2, XVERSE, Command R, and OLMo ([#2694](https://github.com/nomic-ai/gpt4all/pull/2694))
|
||||
- Support DeepSeek-V2 architecture (no Vulkan support) ([#2702](https://github.com/nomic-ai/gpt4all/pull/2702))
|
||||
- Add Llama 3.1 8B Instruct to models3.json (by [@3Simplex](https://github.com/3Simplex) in [#2731](https://github.com/nomic-ai/gpt4all/pull/2731) and [#2732](https://github.com/nomic-ai/gpt4all/pull/2732))
|
||||
- Support Llama 3.1 RoPE scaling ([#2758](https://github.com/nomic-ai/gpt4all/pull/2758))
|
||||
- Add Qwen2-1.5B-Instruct to models3.json (by [@ThiloteE](https://github.com/ThiloteE) in [#2759](https://github.com/nomic-ai/gpt4all/pull/2759))
|
||||
- Detect use of a Python interpreter under Rosetta for a clearer error message ([#2793](https://github.com/nomic-ai/gpt4all/pull/2793))
|
||||
|
||||
### Changed
|
||||
- Build against CUDA 11.8 instead of CUDA 12 for better compatibility with older drivers ([#2639](https://github.com/nomic-ai/gpt4all/pull/2639))
|
||||
- Update llama.cpp to commit 87e397d00 from July 19th ([#2694](https://github.com/nomic-ai/gpt4all/pull/2694))
|
||||
|
||||
### Removed
|
||||
- Remove unused internal llmodel\_has\_gpu\_device ([#2409](https://github.com/nomic-ai/gpt4all/pull/2409))
|
||||
- Remove support for GPT-J models ([#2676](https://github.com/nomic-ai/gpt4all/pull/2676), [#2693](https://github.com/nomic-ai/gpt4all/pull/2693))
|
||||
|
||||
### Fixed
|
||||
- Fix debug mode crash on Windows and undefined behavior in LLamaModel::embedInternal ([#2467](https://github.com/nomic-ai/gpt4all/pull/2467))
|
||||
- Fix CUDA PTX errors with some GPT4All builds ([#2421](https://github.com/nomic-ai/gpt4all/pull/2421))
|
||||
- Fix mishandling of inputs greater than n\_ctx tokens after [#1970](https://github.com/nomic-ai/gpt4all/pull/1970) ([#2498](https://github.com/nomic-ai/gpt4all/pull/2498))
|
||||
- Fix crash when Kompute falls back to CPU ([#2640](https://github.com/nomic-ai/gpt4all/pull/2640))
|
||||
- Fix several Kompute resource management issues ([#2694](https://github.com/nomic-ai/gpt4all/pull/2694))
|
||||
- Fix crash/hang when some models stop generating, by showing special tokens ([#2701](https://github.com/nomic-ai/gpt4all/pull/2701))
|
||||
- Fix several backend issues ([#2778](https://github.com/nomic-ai/gpt4all/pull/2778))
|
||||
- Restore leading space removal logic that was incorrectly removed in [#2694](https://github.com/nomic-ai/gpt4all/pull/2694)
|
||||
- CUDA: Cherry-pick llama.cpp DMMV cols requirement fix that caused a crash with long conversations since [#2694](https://github.com/nomic-ai/gpt4all/pull/2694)
|
||||
|
||||
[Unreleased]: https://github.com/nomic-ai/gpt4all/compare/python-v2.8.2...HEAD
|
||||
[2.8.2]: https://github.com/nomic-ai/gpt4all/compare/python-v2.8.1...python-v2.8.2
|
||||
[2.8.1]: https://github.com/nomic-ai/gpt4all/compare/python-v2.8.0...python-v2.8.1
|
||||
[2.8.0]: https://github.com/nomic-ai/gpt4all/compare/python-v2.7.0...python-v2.8.0
|
||||
19
gpt4all-bindings/python/LICENSE.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2023 Nomic, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
1
gpt4all-bindings/python/MANIFEST.in
Normal file
@@ -0,0 +1 @@
|
||||
recursive-include gpt4all/llmodel_DO_NOT_MODIFY *
|
||||
93
gpt4all-bindings/python/README.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# Python GPT4All
|
||||
|
||||
This package contains a set of Python bindings around the `llmodel` C-API.
|
||||
|
||||
Package on PyPI: https://pypi.org/project/gpt4all/
|
||||
|
||||
## Documentation
|
||||
https://docs.gpt4all.io/gpt4all_python.html
|
||||
|
||||
## Installation
|
||||
|
||||
The easiest way to install the Python bindings for GPT4All is to use pip:
|
||||
|
||||
```
|
||||
pip install gpt4all
|
||||
```
|
||||
|
||||
This will download the latest version of the `gpt4all` package from PyPI.
|
||||
|
||||
## Local Build
|
||||
|
||||
As an alternative to downloading via pip, you may build the Python bindings from source.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
You will need a compiler. On Windows, you should install Visual Studio with the C++ Development components. On macOS, you will need the full version of Xcode—Xcode Command Line Tools lacks certain required tools. On Linux, you will need a GCC or Clang toolchain with C++ support.
|
||||
|
||||
On Windows and Linux, building GPT4All with full GPU support requires the [Vulkan SDK](https://vulkan.lunarg.com/sdk/home) and the latest [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads).
|
||||
|
||||
### Building the python bindings
|
||||
|
||||
1. Clone GPT4All and change directory:
|
||||
```
|
||||
git clone --recurse-submodules https://github.com/nomic-ai/gpt4all.git
|
||||
cd gpt4all/gpt4all-backend
|
||||
```
|
||||
|
||||
2. Build the backend.
|
||||
|
||||
If you are using Windows and have Visual Studio installed:
|
||||
```
|
||||
cmake -B build
|
||||
cmake --build build --parallel --config RelWithDebInfo
|
||||
```
|
||||
|
||||
For all other platforms:
|
||||
```
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
cmake --build build --parallel
|
||||
```
|
||||
|
||||
`RelWithDebInfo` is a good default, but you can also use `Release` or `Debug` depending on the situation.
|
||||
|
||||
2. Install the Python package:
|
||||
```
|
||||
cd ../gpt4all-bindings/python
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Test it out! In a Python script or console:
|
||||
|
||||
```python
|
||||
from gpt4all import GPT4All
|
||||
model = GPT4All("orca-mini-3b-gguf2-q4_0.gguf")
|
||||
output = model.generate("The capital of France is ", max_tokens=3)
|
||||
print(output)
|
||||
```
|
||||
|
||||
|
||||
GPU Usage
|
||||
```python
|
||||
from gpt4all import GPT4All
|
||||
model = GPT4All("orca-mini-3b-gguf2-q4_0.gguf", device='gpu') # device='amd', device='intel'
|
||||
output = model.generate("The capital of France is ", max_tokens=3)
|
||||
print(output)
|
||||
```
|
||||
|
||||
## Troubleshooting a Local Build
|
||||
- If you're on Windows and have compiled with a MinGW toolchain, you might run into an error like:
|
||||
```
|
||||
FileNotFoundError: Could not find module '<...>\gpt4all-bindings\python\gpt4all\llmodel_DO_NOT_MODIFY\build\libllmodel.dll'
|
||||
(or one of its dependencies). Try using the full path with constructor syntax.
|
||||
```
|
||||
The key phrase in this case is _"or one of its dependencies"_. The Python interpreter you're using
|
||||
probably doesn't see the MinGW runtime dependencies. At the moment, the following three are required:
|
||||
`libgcc_s_seh-1.dll`, `libstdc++-6.dll` and `libwinpthread-1.dll`. You should copy them from MinGW
|
||||
into a folder where Python will see them, preferably next to `libllmodel.dll`.
|
||||
|
||||
- Note regarding the Microsoft toolchain: Compiling with MSVC is possible, but not the official way to
|
||||
go about it at the moment. MSVC doesn't produce DLLs with a `lib` prefix, which the bindings expect.
|
||||
You'd have to amend that yourself.
|
||||
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 127 KiB After Width: | Height: | Size: 127 KiB |
|
Before Width: | Height: | Size: 237 KiB After Width: | Height: | Size: 237 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 686 KiB After Width: | Height: | Size: 686 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 113 KiB |
|
Before Width: | Height: | Size: 272 KiB After Width: | Height: | Size: 272 KiB |
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 319 KiB After Width: | Height: | Size: 319 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 531 KiB After Width: | Height: | Size: 531 KiB |
|
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 230 KiB |
|
Before Width: | Height: | Size: 120 KiB After Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 500 KiB After Width: | Height: | Size: 500 KiB |
|
Before Width: | Height: | Size: 349 KiB After Width: | Height: | Size: 349 KiB |
|
Before Width: | Height: | Size: 297 KiB After Width: | Height: | Size: 297 KiB |
|
Before Width: | Height: | Size: 2.2 MiB After Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 192 KiB After Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 188 KiB After Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 584 KiB After Width: | Height: | Size: 584 KiB |
|
Before Width: | Height: | Size: 287 KiB After Width: | Height: | Size: 287 KiB |
|
Before Width: | Height: | Size: 398 KiB After Width: | Height: | Size: 398 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 712 KiB After Width: | Height: | Size: 712 KiB |
|
Before Width: | Height: | Size: 404 KiB After Width: | Height: | Size: 404 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 246 KiB After Width: | Height: | Size: 246 KiB |
|
Before Width: | Height: | Size: 232 KiB After Width: | Height: | Size: 232 KiB |