Skip to content

Commit

Permalink
Merge branch 'main' into docs/add-guides
Browse files Browse the repository at this point in the history
  • Loading branch information
0xHieu01 authored Jan 5, 2024
2 parents f6a1105 + 9cf1701 commit f5b5dfd
Show file tree
Hide file tree
Showing 28 changed files with 429 additions and 112 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,25 +70,25 @@ Jan is an open-source ChatGPT alternative that runs 100% offline on your compute
<tr style="text-align:center">
<td style="text-align:center"><b>Experimental (Nightly Build)</b></td>
<td style="text-align:center">
<a href='https://delta.jan.ai/0.4.3-118/jan-win-x64-0.4.3-118.exe'>
<a href='https://delta.jan.ai/0.4.3-121/jan-win-x64-0.4.3-121.exe'>
<img src='./docs/static/img/windows.png' style="height:14px; width: 14px" />
<b>jan.exe</b>
</a>
</td>
<td style="text-align:center">
<a href='https://delta.jan.ai/0.4.3-118/jan-mac-x64-0.4.3-118.dmg'>
<a href='https://delta.jan.ai/0.4.3-121/jan-mac-x64-0.4.3-121.dmg'>
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
<b>Intel</b>
</a>
</td>
<td style="text-align:center">
<a href='https://delta.jan.ai/0.4.3-118/jan-mac-arm64-0.4.3-118.dmg'>
<a href='https://delta.jan.ai/0.4.3-121/jan-mac-arm64-0.4.3-121.dmg'>
<img src='./docs/static/img/mac.png' style="height:15px; width: 15px" />
<b>M1/M2</b>
</a>
</td>
<td style="text-align:center">
<a href='https://delta.jan.ai/0.4.3-118/jan-linux-amd64-0.4.3-118.deb'>
<a href='https://delta.jan.ai/0.4.3-121/jan-linux-amd64-0.4.3-121.deb'>
<img src='./docs/static/img/linux.png' style="height:14px; width: 14px" />
<b>jan.deb</b>
</a>
Expand Down
60 changes: 60 additions & 0 deletions USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
## Requirements for running Jan App in GPU mode on Windows and Linux
- You must have an NVIDIA driver that supports CUDA 11.4 or higher. Refer [here](https://docs.nvidia.com/deploy/cuda-compatibility/index.html#binary-compatibility__table-toolkit-driver).
To check if the NVIDIA driver is installed, open PowerShell or Terminal and enter the following command:
```bash
nvidia-smi
```
If you see a result similar to the following, you have successfully installed the NVIDIA driver:
```bash
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.57.02 Driver Version: 470.57.02 CUDA Version: 11.4 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA GeForce ... Off | 00000000:01:00.0 On | N/A |
| 0% 51C P8 10W / 170W | 364MiB / 7982MiB | 0% Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
```

- You must have CUDA 11.4 or higher.
To check if CUDA is installed, open PowerShell or Terminal and enter the following command:
```bash
nvcc --version
```
If you see a result similar to the following, you have successfully installed CUDA:
```bash
nvcc: NVIDIA (R) Cuda compiler driver
Cuda compilation tools, release 11.4, V11.4.100
Build cuda_11.4.r11.4/compiler.30033411_0
```

- Specifically for Linux, you will need to have a CUDA compatible driver, refer [here](https://docs.nvidia.com/deploy/cuda-compatibility/index.html#binary-compatibility__table-toolkit-driver), and you must add the `.so` libraries of CUDA and the CUDA compatible driver to the `LD_LIBRARY_PATH` environment variable, refer [here](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#post-installation-actions).

## How to switch mode CPU/GPU Jan app

By default, Jan app will run in CPU mode. When starting Jan app, the program will automatically check if your computer meets the requirements to run in GPU mode. If it does, we will automatically enable GPU mode and pick the GPU has highest VGRAM for you (feature allowing users to select one or more GPU devices for use - currently in planning). You can check whether you are using CPU mode or GPU mode in the settings/advance section of Jan app. (see image below). ![](/docs/static/img/usage/jan-gpu-enable-setting.png)

If you have GPU mode but it is not enabled by default, the following possibilities may exist, you can follow the next steps to fix the error:

1. You have not installed the NVIDIA driver, refer to the NVIDIA driver that supports CUDA 11.4 [here](https://docs.nvidia.com/deploy/cuda-compatibility/index.html#binary-compatibility__table-toolkit-driver).

2. You have not installed the CUDA toolkit or your CUDA toolkit is not compatible with the NVIDIA driver, refer to CUDA compatibility [here](https://docs.nvidia.com/deploy/cuda-compatibility/index.html#binary-compatibility__table-toolkit-driver).

3. You have not installed a CUDA compatible driver, refer [here](https://docs.nvidia.com/deploy/cuda-compatibility/index.html#binary-compatibility__table-toolkit-driver), and you must add the `.so` libraries of CUDA and the CUDA compatible driver to the `LD_LIBRARY_PATH` environment variable, refer [here](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#post-installation-actions). For Windows, add the `.dll` libraries of CUDA and the CUDA compatible driver to the `PATH` environment variable. Usually, when installing CUDA on Windows, this environment variable is automatically added, but if you do not see it, you can add it manually by referring [here](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html#environment-setup).

## To check the current GPU-related settings that Jan app has detected, you can go to the Settings/Advanced section as shown in the image below.
![](/docs/static/img/usage/jan-open-home-directory.png)
![](/docs/static/img/usage/jan-open-settings-1.png)
![](/docs/static/img/usage/jan-open-settings-2.png)
![](/docs/static/img/usage/jan-open-settings-3.png)

When you have an issue with GPU mode, share the `settings.json` with us will help us to solve the problem faster.

## Tested on

- Windows 11 Pro 64-bit, NVIDIA GeForce RTX 4070ti GPU, CUDA 12.2, NVIDIA driver 531.18
- Ubuntu 22.04 LTS, NVIDIA GeForce RTX 4070ti GPU, CUDA 12.2, NVIDIA driver 545
3 changes: 2 additions & 1 deletion core/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,10 @@ export enum FileSystemRoute {
writeFileSync = 'writeFileSync',
}
export enum FileManagerRoute {
synceFile = 'syncFile',
syncFile = 'syncFile',
getUserSpace = 'getUserSpace',
getResourcePath = 'getResourcePath',
fileStat = 'fileStat',
}

export type ApiFunction = (...args: any[]) => any
Expand Down
12 changes: 12 additions & 0 deletions core/src/core.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { FileStat } from './types'

/**
* Execute a extension module function in main process
*
Expand Down Expand Up @@ -74,6 +76,15 @@ const openExternalUrl: (url: string) => Promise<any> = (url) =>
*/
const getResourcePath: () => Promise<string> = () => global.core.api?.getResourcePath()

/**
* Gets the file's stats.
*
* @param path - The path to the file.
* @returns {Promise<FileStat>} - A promise that resolves with the file's stats.
*/
const fileStat: (path: string) => Promise<FileStat | undefined> = (path) =>
global.core.api?.fileStat(path)

/**
* Register extension point function type definition
*/
Expand All @@ -97,4 +108,5 @@ export {
joinPath,
openExternalUrl,
baseName,
fileStat,
}
12 changes: 12 additions & 0 deletions core/src/node/api/routes/fileManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { FileManagerRoute } from '../../../api'
import { HttpServer } from '../../index'

export const fsRouter = async (app: HttpServer) => {
app.post(`/app/${FileManagerRoute.syncFile}`, async (request: any, reply: any) => {})

app.post(`/app/${FileManagerRoute.getUserSpace}`, async (request: any, reply: any) => {})

app.post(`/app/${FileManagerRoute.getResourcePath}`, async (request: any, reply: any) => {})

app.post(`/app/${FileManagerRoute.fileStat}`, async (request: any, reply: any) => {})
}
4 changes: 4 additions & 0 deletions core/src/types/file/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type FileStat = {
isDirectory: boolean
size: number
}
1 change: 1 addition & 0 deletions core/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './thread'
export * from './message'
export * from './inference'
export * from './monitoring'
export * from './file'
Binary file added docs/static/img/usage/jan-gpu-enable-setting.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/usage/jan-open-settings-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/usage/jan-open-settings-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/static/img/usage/jan-open-settings-3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 34 additions & 5 deletions electron/handlers/fileManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import reflect from '@alumna/reflect'

import { FileManagerRoute } from '@janhq/core'
import { userSpacePath, getResourcePath } from './../utils/path'
import fs from 'fs'
import { join } from 'path'
import { FileStat } from '@janhq/core/.'

/**
* Handles file system extensions operations.
*/
export function handleFileMangerIPCs() {
// Handles the 'synceFile' IPC event. This event is triggered to synchronize a file from a source path to a destination path.
// Handles the 'syncFile' IPC event. This event is triggered to synchronize a file from a source path to a destination path.
ipcMain.handle(
FileManagerRoute.synceFile,
FileManagerRoute.syncFile,
async (_event, src: string, dest: string) => {
return reflect({
src,
Expand All @@ -31,7 +34,33 @@ export function handleFileMangerIPCs() {
)

// Handles the 'getResourcePath' IPC event. This event is triggered to get the resource path.
ipcMain.handle(FileManagerRoute.getResourcePath, async (_event) => {
return getResourcePath()
})
ipcMain.handle(FileManagerRoute.getResourcePath, async (_event) =>
getResourcePath()
)

// handle fs is directory here
ipcMain.handle(
FileManagerRoute.fileStat,
async (_event, path: string): Promise<FileStat | undefined> => {
const normalizedPath = path
.replace(`file://`, '')
.replace(`file:/`, '')
.replace(`file:\\\\`, '')
.replace(`file:\\`, '')

const fullPath = join(userSpacePath, normalizedPath)
const isExist = fs.existsSync(fullPath)
if (!isExist) return undefined

const isDirectory = fs.lstatSync(fullPath).isDirectory()
const size = fs.statSync(fullPath).size

const fileStat: FileStat = {
isDirectory,
size,
}

return fileStat
}
)
}
2 changes: 1 addition & 1 deletion extensions/inference-nitro-extension/bin/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.32
0.1.34
2 changes: 1 addition & 1 deletion extensions/inference-nitro-extension/download.bat
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
@echo off
set /p NITRO_VERSION=<./bin/version.txt
.\node_modules\.bin\download https://github.com/janhq/nitro/releases/download/v%NITRO_VERSION%/nitro-%NITRO_VERSION%-win-amd64-cuda.tar.gz -e --strip 1 -o ./bin/win-cuda && .\node_modules\.bin\download https://github.com/janhq/nitro/releases/download/v%NITRO_VERSION%/nitro-%NITRO_VERSION%-win-amd64.tar.gz -e --strip 1 -o ./bin/win-cpu
.\node_modules\.bin\download https://github.com/janhq/nitro/releases/download/v%NITRO_VERSION%/nitro-%NITRO_VERSION%-win-amd64-cuda-12-0.tar.gz -e --strip 1 -o ./bin/win-cuda-12-0 && .\node_modules\.bin\download https://github.com/janhq/nitro/releases/download/v%NITRO_VERSION%/nitro-%NITRO_VERSION%-win-amd64-cuda-11-4.tar.gz -e --strip 1 -o ./bin/win-cuda-11-4 && .\node_modules\.bin\download https://github.com/janhq/nitro/releases/download/v%NITRO_VERSION%/nitro-%NITRO_VERSION%-win-amd64.tar.gz -e --strip 1 -o ./bin/win-cpu
2 changes: 1 addition & 1 deletion extensions/inference-nitro-extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"license": "AGPL-3.0",
"scripts": {
"build": "tsc -b . && webpack --config webpack.config.js",
"downloadnitro:linux": "NITRO_VERSION=$(cat ./bin/version.txt) && download https://github.com/janhq/nitro/releases/download/v${NITRO_VERSION}/nitro-${NITRO_VERSION}-linux-amd64.tar.gz -e --strip 1 -o ./bin/linux-cpu && chmod +x ./bin/linux-cpu/nitro && download https://github.com/janhq/nitro/releases/download/v${NITRO_VERSION}/nitro-${NITRO_VERSION}-linux-amd64-cuda.tar.gz -e --strip 1 -o ./bin/linux-cuda && chmod +x ./bin/linux-cuda/nitro",
"downloadnitro:linux": "NITRO_VERSION=$(cat ./bin/version.txt) && download https://github.com/janhq/nitro/releases/download/v${NITRO_VERSION}/nitro-${NITRO_VERSION}-linux-amd64.tar.gz -e --strip 1 -o ./bin/linux-cpu && chmod +x ./bin/linux-cpu/nitro && download https://github.com/janhq/nitro/releases/download/v${NITRO_VERSION}/nitro-${NITRO_VERSION}-linux-amd64-cuda-12-0.tar.gz -e --strip 1 -o ./bin/linux-cuda-12-0 && chmod +x ./bin/linux-cuda-12-0/nitro && download https://github.com/janhq/nitro/releases/download/v${NITRO_VERSION}/nitro-${NITRO_VERSION}-linux-amd64-cuda-11-4.tar.gz -e --strip 1 -o ./bin/linux-cuda-11-4 && chmod +x ./bin/linux-cuda-11-4/nitro",
"downloadnitro:darwin": "NITRO_VERSION=$(cat ./bin/version.txt) && download https://github.com/janhq/nitro/releases/download/v${NITRO_VERSION}/nitro-${NITRO_VERSION}-mac-arm64.tar.gz -e --strip 1 -o ./bin/mac-arm64 && chmod +x ./bin/mac-arm64/nitro && download https://github.com/janhq/nitro/releases/download/v${NITRO_VERSION}/nitro-${NITRO_VERSION}-mac-amd64.tar.gz -e --strip 1 -o ./bin/mac-x64 && chmod +x ./bin/mac-x64/nitro",
"downloadnitro:win32": "download.bat",
"downloadnitro": "run-script-os",
Expand Down
8 changes: 4 additions & 4 deletions extensions/inference-nitro-extension/src/helpers/sse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ export function requestInference(
signal: controller?.signal,
})
.then(async (response) => {
if (model.parameters.stream) {
if (model.parameters.stream === false) {
const data = await response.json();
subscriber.next(data.choices[0]?.message?.content ?? "");
} else {
const stream = response.body;
const decoder = new TextDecoder("utf-8");
const reader = stream?.getReader();
Expand All @@ -54,9 +57,6 @@ export function requestInference(
}
}
}
} else {
const data = await response.json();
subscriber.next(data.choices[0]?.message?.content ?? "");
}
subscriber.complete();
})
Expand Down
55 changes: 39 additions & 16 deletions extensions/inference-nitro-extension/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,28 +85,40 @@ function checkFileExistenceInPaths(file: string, paths: string[]): boolean {
}

function updateCudaExistence() {
let files: string[];
let filesCuda12: string[];
let filesCuda11: string[];
let paths: string[];
let cudaVersion: string = "";

if (process.platform === "win32") {
files = ["cublas64_12.dll", "cudart64_12.dll", "cublasLt64_12.dll"];
filesCuda12 = ["cublas64_12.dll", "cudart64_12.dll", "cublasLt64_12.dll"];
filesCuda11 = ["cublas64_11.dll", "cudart64_11.dll", "cublasLt64_11.dll"];
paths = process.env.PATH ? process.env.PATH.split(path.delimiter) : [];
const nitro_cuda_path = path.join(__dirname, "bin", "win-cuda");
paths.push(nitro_cuda_path);
} else {
files = ["libcudart.so.12", "libcublas.so.12", "libcublasLt.so.12"];
filesCuda12 = ["libcudart.so.12", "libcublas.so.12", "libcublasLt.so.12"];
filesCuda11 = ["libcudart.so.11.0", "libcublas.so.11", "libcublasLt.so.11"];
paths = process.env.LD_LIBRARY_PATH
? process.env.LD_LIBRARY_PATH.split(path.delimiter)
: [];
const nitro_cuda_path = path.join(__dirname, "bin", "linux-cuda");
paths.push(nitro_cuda_path);
paths.push("/usr/lib/x86_64-linux-gnu/");
}

let cudaExists = files.every(
let cudaExists = filesCuda12.every(
(file) => existsSync(file) || checkFileExistenceInPaths(file, paths)
);

if (!cudaExists) {
cudaExists = filesCuda11.every(
(file) => existsSync(file) || checkFileExistenceInPaths(file, paths)
);
if (cudaExists) {
cudaVersion = "11";
}
}
else {
cudaVersion = "12";
}

let data;
try {
data = JSON.parse(readFileSync(NVIDIA_INFO_FILE, "utf-8"));
Expand All @@ -115,6 +127,7 @@ function updateCudaExistence() {
}

data["cuda"].exist = cudaExists;
data["cuda"].version = cudaVersion;
if (cudaExists) {
data.run_mode = "gpu";
}
Expand Down Expand Up @@ -376,12 +389,17 @@ function spawnNitroProcess(nitroResourceProbe: any): Promise<any> {
let cudaVisibleDevices = "";
let binaryName;
if (process.platform === "win32") {
let nvida_info = JSON.parse(readFileSync(NVIDIA_INFO_FILE, "utf-8"));
if (nvida_info["run_mode"] === "cpu") {
let nvidiaInfo = JSON.parse(readFileSync(NVIDIA_INFO_FILE, "utf-8"));
if (nvidiaInfo["run_mode"] === "cpu") {
binaryFolder = path.join(binaryFolder, "win-cpu");
} else {
binaryFolder = path.join(binaryFolder, "win-cuda");
cudaVisibleDevices = nvida_info["gpu_highest_vram"];
if (nvidiaInfo["cuda"].version === "12") {
binaryFolder = path.join(binaryFolder, "win-cuda-12-0");
}
else {
binaryFolder = path.join(binaryFolder, "win-cuda-11-4");
}
cudaVisibleDevices = nvidiaInfo["gpu_highest_vram"];
}
binaryName = "nitro.exe";
} else if (process.platform === "darwin") {
Expand All @@ -392,12 +410,17 @@ function spawnNitroProcess(nitroResourceProbe: any): Promise<any> {
}
binaryName = "nitro";
} else {
let nvida_info = JSON.parse(readFileSync(NVIDIA_INFO_FILE, "utf-8"));
if (nvida_info["run_mode"] === "cpu") {
let nvidiaInfo = JSON.parse(readFileSync(NVIDIA_INFO_FILE, "utf-8"));
if (nvidiaInfo["run_mode"] === "cpu") {
binaryFolder = path.join(binaryFolder, "linux-cpu");
} else {
binaryFolder = path.join(binaryFolder, "linux-cuda");
cudaVisibleDevices = nvida_info["gpu_highest_vram"];
if (nvidiaInfo["cuda"].version === "12") {
binaryFolder = path.join(binaryFolder, "linux-cuda-12-0");
}
else {
binaryFolder = path.join(binaryFolder, "linux-cuda-11-4");
}
cudaVisibleDevices = nvidiaInfo["gpu_highest_vram"];
}
binaryName = "nitro";
}
Expand Down
8 changes: 4 additions & 4 deletions extensions/inference-openai-extension/src/helpers/sse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ export function requestInference(
subscriber.complete();
return;
}
if (model.parameters.stream) {
if (model.parameters.stream === false) {
const data = await response.json();
subscriber.next(data.choices[0]?.message?.content ?? "");
} else {
const stream = response.body;
const decoder = new TextDecoder("utf-8");
const reader = stream?.getReader();
Expand All @@ -70,9 +73,6 @@ export function requestInference(
}
}
}
} else {
const data = await response.json();
subscriber.next(data.choices[0]?.message?.content ?? "");
}
subscriber.complete();
})
Expand Down
Loading

0 comments on commit f5b5dfd

Please sign in to comment.