Skip to content
Closed

LLMs #140

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 3 additions & 17 deletions llms/Judge/canister_ids.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,22 @@
"demo": "4uqyf-biaaa-aaaae-qfctq-cai",
"development": "fhlsk-5aaaa-aaaaf-qapuq-cai",
"ic": "xcke3-5qaaa-aaaaj-az4na-cai",
"prd": "vva3l-3iaaa-aaaac-qal2a-cai",
"testing": "dfcrj-fiaaa-aaaab-qb2vq-cai"
"prd": "vva3l-3iaaa-aaaac-qal2a-cai"
},
"llm_10": {
"prd": "vl3dc-4yaaa-aaaaj-qnpwq-cai"
},
"llm_11": {
"prd": "vcyi6-kqaaa-aaaaj-qnpxa-cai"
},
"llm_12": {
"prd": "vfzok-hiaaa-aaaaj-qnpxq-cai"
},
"llm_13": {
"prd": "nnrl2-3iaaa-aaaai-atkjq-cai"
},
"llm_14": {
"prd": "nyw2x-2aaaa-aaaai-atkka-cai"
},
"llm_15": {
"prd": "n7x4d-xyaaa-aaaai-atkkq-cai"
},
"llm_2": {
"prd": "kg5kw-bqaaa-aaaam-aeltq-cai",
"testing": "dqfae-eaaaa-aaaab-qb2wa-cai"
"prd": "kg5kw-bqaaa-aaaam-aeltq-cai"
},
"llm_3": {
"prd": "lltoy-oyaaa-aaaam-aelua-cai"
Expand All @@ -44,16 +36,10 @@
"llm_5": {
"prd": "o5nld-ziaaa-aaaah-arfxa-cai"
},
"llm_6": {
"prd": "o2mnx-uqaaa-aaaah-arfxq-cai"
},
"llm_7": {
"prd": "v7zwd-iqaaa-aaaad-aapqa-cai"
},
"llm_8": {
"prd": "vyyqx-fiaaa-aaaad-aapqq-cai"
},
"llm_9": {
"prd": "vr33l-taaaa-aaaad-aapra-cai"
}
}
}
2 changes: 1 addition & 1 deletion llms/llama_cpp_canister/README-instructions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# llama_cpp_canister

How to upgrade IConfucius to a new version of llama_cpp_canister:
How to upgrade funnAI LLMs to a new version of llama_cpp_canister:

- Remove everything except README-instructions.md from this folder
- Download llama_cpp_canister_v#.#.#.zip from https://github.com/onicai/llama_cpp_canister/releases
Expand Down
62 changes: 58 additions & 4 deletions llms/llama_cpp_canister/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,29 +49,51 @@ You can just grab the latest [release](https://github.com/onicai/llama_cpp_canis

# Set up

- Install dfx:
- Install dfx (version 0.31.0 or later is required):

```bash
sh -ci "$(curl -fsSL https://internetcomputer.org/install.sh)"

# Configure your shell
source "$HOME/.local/share/dfx/env"

# Verify the version (must be >= 0.31.0)
dfx --version
```

> **Note:** dfx 0.31+ is required because `icp-py-core` uses the `/api/v3/`
> endpoint, which is not supported by older dfx versions.

- Clone the repo and it's children:

_(skip when using the [release](https://github.com/onicai/llama_cpp_canister/releases))_

Approach 1: HTTPS — no GitHub SSH keys required

```bash
# Clone this repository
git clone https://github.com/onicai/llama_cpp_canister.git
cd llama_cpp_canister

# Clone llama_cpp_onicai_fork (our fork of llama.cpp) into ./src
cd src
git clone https://github.com/onicai/llama_cpp_onicai_fork.git
```

Approach 2: SSH — requires a configured GitHub SSH key
```bash
# Clone this repo
# Clone this repository
git clone git@github.com:onicai/llama_cpp_canister.git
cd llama_cpp_canister

# Clone llama_cpp_onicai_fork, our forked version of llama.cpp
# Into the ./src folder
# Clone llama_cpp_onicai_fork into ./src
cd src
git clone git@github.com:onicai/llama_cpp_onicai_fork.git
```

Note: If you see Permission denied (publickey) errors, use the HTTPS method above or configure an SSH key in your GitHub account.


- Create a Python environment with dependencies installed

❗❗❗ Use Python 3.11 _(This is needed for binaryen.py dependency)_ ❗❗❗
Expand Down Expand Up @@ -620,6 +642,38 @@ dfx canister call llama_cpp get_creation_timestamp_ns '(record {filename = "<fil
dfx canister call llama_cpp filesystem_remove '(record {filename = "<filename>"})'
```

# Wasm Verification (pre onicai SNS)

> **NOTE:** This workflow was created for the **pre onicai SNS verification
> process** ([NNS Proposal 140268](https://dashboard.internetcomputer.org/proposal/140268)).
> It pins the build environment to icpp-pro 5.3.0 / Rust 1.86.0 to reproduce the
> exact wasm from the v0.7.3 release that is currently deployed to the funnAI LLM
> canisters. **Post onicai SNS, the build process and pinned versions must be
> updated** to match the then-current release and toolchain.

The GitHub Actions workflow [verify-funnAI-LLMs](.github/workflows/verify-funnAI-LLMs.yml) verifies that the `llama_cpp.wasm` built from this repo matches the wasm deployed to the funnAI LLM canisters on the Internet Computer mainnet.

Anyone can independently verify that the on-chain LLM canisters are running the exact code from this open-source repo.

**What it does:**

1. Builds `llama_cpp.wasm` from source (same build steps as the release workflow)
2. Computes the sha256 hash of the built wasm
3. Queries the module hash of each deployed funnAI LLM canister on IC mainnet via `dfx canister info`
4. Compares the hashes and reports pass/fail for each canister

**Canisters verified (30 total):**

| Category | Count | Description |
| ------------------------------- | ----- | ------------------------------------------ |
| funnAI Challenger LLM | 1 | Generates challenges for the funnAI game |
| funnAI Judge LLMs | 16 | Judge responses in the funnAI game |
| funnAI mAIner ShareService LLMs | 13 | Provide LLM inference for mAIner services |

**How to run:**

Trigger the workflow manually from the Actions tab on GitHub (`workflow_dispatch`).

# Appendix A: max_tokens

The size and settings for models impact the number of tokens that can be generated
Expand Down
Binary file modified llms/llama_cpp_canister/build/llama_cpp.wasm
Binary file not shown.
4 changes: 2 additions & 2 deletions llms/llama_cpp_canister/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

-r scripts/requirements.txt
-r src/llama_cpp_onicai_fork/requirements.txt
icpp-pro>=5.3.0
ic-py==1.0.1
icpp-pro>=5.3.1
icp-py-core==2.3.0
binaryen.py
20 changes: 11 additions & 9 deletions llms/llama_cpp_canister/scripts/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import sys
from pathlib import Path
from typing import List
from .ic_py_canister import get_canister, run_dfx_command
from .ic_py_canister import extract_variant, get_canister, run_dfx_command
from .parse_args_download import parse_args
from .calculate_sha256 import calculate_sha256

Expand Down Expand Up @@ -64,13 +64,14 @@ def main() -> int:
)

# ---------------------------------------------------------------------------
# get ic-py based Canister instance
# get icp-py-core based Canister instance
canister_instance = get_canister(canister_name, candid_path, network, canister_id)

# check health (liveness)
print("--\nChecking liveness of canister (did we deploy it!)")
response = canister_instance.health()
if "Ok" in response[0].keys():
result = extract_variant(response)
if "Ok" in result:
print("Ok!")
else:
print("Not OK, response is:")
Expand Down Expand Up @@ -104,11 +105,12 @@ def main() -> int:
}
)

if "Ok" in response[0].keys():
r_filesize = response[0]["Ok"]["filesize"]
r_chunk: List[int] = response[0]["Ok"]["chunk"]
r_chunksize = response[0]["Ok"]["chunksize"]
r_offset = response[0]["Ok"]["offset"]
result = extract_variant(response)
if "Ok" in result:
r_filesize = result["Ok"]["filesize"]
r_chunk: List[int] = result["Ok"]["chunk"]
r_chunksize = result["Ok"]["chunksize"]
r_offset = result["Ok"]["offset"]
total_received = offset + len(r_chunk)
print(
"--"
Expand All @@ -123,7 +125,7 @@ def main() -> int:

f.write(bytearray(r_chunk))

done = response[0]["Ok"]["done"]
done = result["Ok"]["done"]
else:
print("Something went wrong:")
print(response)
Expand Down
28 changes: 19 additions & 9 deletions llms/llama_cpp_canister/scripts/ic_py_canister.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
"""Returns the ic-py Canister instance, for calling the endpoints."""
"""Returns the icp-py-core Canister instance, for calling the endpoints."""

import sys
import subprocess
from pathlib import Path
from typing import Optional
from ic.canister import Canister # type: ignore
from ic.client import Client # type: ignore
from ic.identity import Identity # type: ignore
from ic.agent import Agent # type: ignore
from typing import Any, List, Optional
from icp_core import Agent, Identity, Client, Canister
from icpp.run_shell_cmd import run_shell_cmd

ROOT_PATH = Path(__file__).parent.parent
Expand All @@ -16,6 +13,19 @@
DFX = "dfx"


def extract_variant(response: List[Any]) -> Any:
"""Extract variant result from icp-py-core response.

icp-py-core returns: [{'type': 'variant', 'value': {'Ok': {...}}}]
old ic-py returned: [{'Ok': {...}}]
This helper normalizes both formats to {'Ok': {...}} or {'Err': ...}.
"""
item = response[0]
if "value" in item:
return item["value"]
return item


def run_dfx_command(cmd: str, quiet: bool = False) -> Optional[str]:
"""Runs dfx command as a subprocess"""
try:
Expand All @@ -27,7 +37,7 @@ def run_dfx_command(cmd: str, quiet: bool = False) -> Optional[str]:


def get_agent(network: str = "local") -> Agent:
"""Returns an ic_py Agent instance"""
"""Returns an icp-py-core Agent instance"""

# Check if the network is up
print(f"--\nChecking if the {network} network is up...")
Expand Down Expand Up @@ -82,7 +92,7 @@ def get_canister(
network: str = "local",
canister_id: Optional[str] = "",
) -> Canister:
"""Returns an ic_py Canister instance"""
"""Returns an icp-py-core Canister instance"""

agent = get_agent(network=network)

Expand All @@ -104,4 +114,4 @@ def get_canister(
canister_did = f.read()

# Create a Canister instance
return Canister(agent=agent, canister_id=canister_id, candid=canister_did)
return Canister(agent=agent, canister_id=canister_id, candid_str=canister_did)
39 changes: 22 additions & 17 deletions llms/llama_cpp_canister/scripts/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from pathlib import Path
from typing import Generator
from .calculate_sha256 import calculate_sha256
from .ic_py_canister import get_canister, run_dfx_command
from .ic_py_canister import extract_variant, get_canister, run_dfx_command
from .parse_args_upload import parse_args

ROOT_PATH = Path(__file__).parent.parent
Expand Down Expand Up @@ -88,13 +88,14 @@ def main() -> int:
)

# ---------------------------------------------------------------------------
# get ic-py based Canister instance
# get icp-py-core based Canister instance
canister_instance = get_canister(canister_name, candid_path, network, canister_id)

# check health (liveness)
print("--\nChecking liveness of canister (did we deploy it!)")
response = canister_instance.health()
if "Ok" in response[0].keys():
result = extract_variant(response)
if "Ok" in result:
print("Ok!")
else:
print("Not OK, response is:")
Expand Down Expand Up @@ -163,7 +164,8 @@ def main() -> int:
"chunk": chunk,
"chunksize": chunksize,
"offset": offset,
}
},
verify_certificate=False,
) # pylint: disable=no-member
else:
response = canister_instance.file_upload_chunk(
Expand All @@ -172,7 +174,8 @@ def main() -> int:
"chunk": chunk,
"chunksize": chunksize,
"offset": offset,
}
},
verify_certificate=False,
) # pylint: disable=no-member

break # Exit the loop if the request is successful
Expand All @@ -187,24 +190,25 @@ def main() -> int:
print(f"Retrying in {retry_delay} seconds...")
time.sleep(retry_delay) # Wait before retrying

if "Ok" in response[0].keys():
result = extract_variant(response)
if "Ok" in result:
if DEBUG_VERBOSE == 0:
pass
elif DEBUG_VERBOSE == 1:
# print only every 10th chunk or if it is the last chunk
if i % 10 == 0 or (offset + len(chunk)) >= len(file_bytes):
print(
f"OK! filesize = {response[0]['Ok']['filesize']}, "
f"filesha256 = {response[0]['Ok']['filesha256']}"
f"OK! filesize = {result['Ok']['filesize']}, "
f"filesha256 = {result['Ok']['filesha256']}"
)
else:
print(
f"OK! filesize = {response[0]['Ok']['filesize']}, "
f"filesha256 = {response[0]['Ok']['filesha256']}"
f"OK! filesize = {result['Ok']['filesize']}, "
f"filesha256 = {result['Ok']['filesha256']}"
)

canister_filesize = response[0]["Ok"]["filesize"]
canister_filesha256 = response[0]["Ok"]["filesha256"]
canister_filesize = result["Ok"]["filesize"]
canister_filesha256 = result["Ok"]["filesha256"]
else:
print("Something went wrong:")
print(response)
Expand Down Expand Up @@ -245,14 +249,15 @@ def main() -> int:
{"filename": canister_filename}
)

if "Ok" in response[0].keys():
result = extract_variant(response)
if "Ok" in result:
print(
f"OK! filesize = {response[0]['Ok']['filesize']}, "
f"filesha256 = {response[0]['Ok']['filesha256']}"
f"OK! filesize = {result['Ok']['filesize']}, "
f"filesha256 = {result['Ok']['filesha256']}"
)

canister_filesize = response[0]["Ok"]["filesize"]
canister_filesha256 = response[0]["Ok"]["filesha256"]
canister_filesize = result["Ok"]["filesize"]
canister_filesha256 = result["Ok"]["filesha256"]

if (canister_filesize != local_file_size) or (
canister_filesha256 != local_file_sha256
Expand Down
2 changes: 1 addition & 1 deletion llms/llama_cpp_canister/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.7.3
0.9.0
Loading