Skip to content

Commit

Permalink
Merge pull request #27 from ritual-net/sr/feat/remove_infernet_ml
Browse files Browse the repository at this point in the history
Remove infernet_ml
  • Loading branch information
arshan-ritual authored Oct 28, 2024
2 parents 9b69f49 + 3a30ceb commit 5bdf085
Show file tree
Hide file tree
Showing 58 changed files with 578 additions and 2,486 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,9 @@ remote_sync

# secrets
*-key.json

# Virtual envs
**/env/**

# Arweave keyfile
keyfile-*.json
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ 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.0.0/).
- ##### This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.0.0] - 2024-10-28

### Changed
- Simplified examples to the minimum core functionality necessary and removed all dependencies on `infernet-ml`.
- Updated images used for deploying the Infernet Node.

## [1.0.2] - 2024-07-31

### Changed
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ build-container:

remove-containers:
docker compose -f deploy/docker-compose.yaml down || true
docker stop $(project) anvil-node && docker rm $(project) anvil-node || true
docker stop $(project) infernet-anvil && docker rm $(project) infernet-anvil || true

build-multiplatform:
$(MAKE) -C ./projects/$(project)/container build-multiplatform
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ model to infernet. Using this example will make it easier for you to deploy your
4. [Prompt to NFT](projects/prompt-to-nft/prompt-to-nft.md): In this example, we use [stablediffusion](https://github.com/Stability-AI/stablediffusion) to
mint NFTs on-chain using a prompt.
5. [TGI Inference with Mistral-7b](projects/tgi-llm/tgi-llm.md): This example shows you how to deploy an arbitrary
LLM model using [Huggingface's TGI](https://huggingface.co/docs/text-generation-inference/en/index), and use it with an infernet node.
LLM model using [Huggingface's TGI](https://huggingface.co/docs/text-generation-inference/en/index), and use it with an Infernet Node.
6. [Running OpenAI's GPT-4 on Infernet](projects/gpt4/gpt4.md): This example shows you how to deploy OpenAI's GPT-4 model
to infernet.
4 changes: 3 additions & 1 deletion deploy/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
services:
node:
image: ritualnetwork/infernet-node:1.0.0
image: ritualnetwork/infernet-node:1.3.1
ports:
- "0.0.0.0:4000:4000"
volumes:
Expand Down Expand Up @@ -31,6 +31,7 @@ services:
- redis-data:/data
restart:
on-failure
container_name: infernet-redis

fluentbit:
image: fluent/fluent-bit:3.1.4
Expand All @@ -45,6 +46,7 @@ services:
- network
restart:
on-failure
container_name: infernet-fluentbit

infernet-anvil:
image: ritualnetwork/infernet-anvil:1.0.0
Expand Down
2 changes: 1 addition & 1 deletion projects/gpt4/container/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ ADD https://astral.sh/uv/install.sh /install.sh
RUN chmod 755 /install.sh
RUN /install.sh && rm /install.sh

COPY src/requirements.txt .
COPY requirements.txt .

RUN /root/.cargo/bin/uv pip install --system --no-cache -r requirements.txt

Expand Down
32 changes: 27 additions & 5 deletions projects/gpt4/container/README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,42 @@
# GPT 4
In this example, we run a minimalist container that makes use of our closed-source model
workflow: `CSSInferenceWorkflow`. Refer to [src/app.py](src/app.py) for the
implementation of the quart application.

In this example, we will run a minimalist container that makes use of the OpenAI [completions API](https://platform.openai.com/docs/api-reference/chat) to serve text generation requests.

Check out the full tutorial [here](https://learn.ritual.net/examples/running_gpt_4).

## Requirements
To use the model you'll need to have an OpenAI api key. Get one at
[OpenAI](https://openai.com/)'s website.

To use the model you'll need to have an OpenAI API key. Get one on [OpenAI](https://openai.com/)'s website.

## Build the Container

Simply run the following command to build the container:

```bash
make build
```

## Run the Container

To run the container, you can use the following command:

```bash
make run
```

## Test the Container

You can test the container by making inference requests directly via your terminal:

```bash
curl -X POST localhost:3000/service_output -H "Content-Type: application/json" \
-d '{"source": 1, "data": {"prompt": "can shrimps actually fry rice?"}}'
```

## Next steps

This container is for demonstration purposes only, and is purposefully simplified for
readability and ease of comprehension. For a production-ready version of this code, check out:

- The [CSS Inference Workflow](https://infernet-ml.docs.ritual.net/reference/infernet_ml/workflows/inference/css_inference_workflow/): A Python class that supports multiple API providers, including OpenAI, and can be used to build production-ready containers.
- The [CSS Inference Service](https://infernet-services.docs.ritual.net/reference/css_inference_service/): A production-ready, [Infernet](https://docs.ritual.net/infernet/node/introduction)-compatible container that works out-of-the-box with minimal configuration, and serves inference using the `CSS Inference Workflow`.
8 changes: 5 additions & 3 deletions projects/gpt4/container/config.sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
"allowed_sim_errors": []
},
"snapshot_sync": {
"sleep": 3,
"batch_size": 100
"sleep": 1.5,
"batch_size": 50,
"starting_sub_id": 0,
"sync_period": 1
}
},
"startup_wait": 1.0,
Expand All @@ -43,7 +45,7 @@
"allowed_ips": [],
"command": "--bind=0.0.0.0:3000 --workers=2",
"env": {
"OPENAI_API_KEY": "your-key"
"OPENAI_API_KEY": "your-openai-key"
},
"volumes": [],
"accepted_payments": {},
Expand Down
2 changes: 2 additions & 0 deletions projects/gpt4/container/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
quart==0.19.4
web3==6.15.0
120 changes: 56 additions & 64 deletions projects/gpt4/container/src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,15 @@
from typing import Any, cast

from eth_abi import decode, encode # type: ignore
from infernet_ml.utils.css_mux import (
ConvoMessage,
CSSCompletionParams,
CSSRequest,
Provider,
)
from infernet_ml.utils.service_models import InfernetInput
from infernet_ml.utils.service_models import JobLocation
from infernet_ml.workflows.inference.css_inference_workflow import CSSInferenceWorkflow
from quart import Quart, request
import requests

log = logging.getLogger(__name__)


def create_app() -> Quart:
app = Quart(__name__)

workflow = CSSInferenceWorkflow(
api_keys={Provider.OPENAI: os.environ["OPENAI_API_KEY"]}
)

workflow.setup()

@app.route("/")
def index() -> str:
"""
Expand All @@ -35,70 +21,76 @@ def index() -> str:

@app.route("/service_output", methods=["POST"])
async def inference() -> Any:
req_data = await request.get_json()
"""
InfernetInput has the format:
Input data has the format:
source: (0 on-chain, 1 off-chain)
destination: (0 on-chain, 1 off-chain)
data: dict[str, Any]
"""
infernet_input: InfernetInput = InfernetInput(**req_data)
req_data: dict[str, Any] = await request.get_json()
onchain_source = True if req_data.get("source") == 0 else False
onchain_destination = True if req_data.get("destination") == 0 else False
data = req_data.get("data")

match infernet_input:
case InfernetInput(source=JobLocation.OFFCHAIN):
prompt = cast(dict[str, Any], infernet_input.data).get("prompt")
case InfernetInput(source=JobLocation.ONCHAIN):
# On-chain requests are sent as a generalized hex-string which we will
# decode to the appropriate format.
(prompt,) = decode(
["string"], bytes.fromhex(cast(str, infernet_input.data))
)
case _:
raise ValueError("Invalid source")
if onchain_source:
"""
For on-chain requests, the prompt is sent as a generalized hex-string
which we will decode to the appropriate format.
"""
(prompt,) = decode(["string"], bytes.fromhex(cast(str, data)))
else:
"""For off-chain requests, the prompt is sent as is."""
prompt = cast(dict[str, Any], data).get("prompt")

result = workflow.inference(
CSSRequest(
provider=Provider.OPENAI,
endpoint="completions",
model="gpt-4-0613",
params=CSSCompletionParams(
messages=[
ConvoMessage(
role="system", content="you are a helpful " "assistant."
),
ConvoMessage(role="user", content=cast(str, prompt)),
]
),
)
# Make request to the OpenAI API to get a completion of the prompt.
# See https://platform.openai.com/docs/api-reference/chat for more info.
api_key = os.environ["OPENAI_API_KEY"]
response = requests.post(
"https://api.openai.com/v1/chat/completions",
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}",
},
json={
"model": "gpt-4-0613",
"messages": [
{"role": "system", "content": "you are a helpful assistant."},
{"role": "user", "content": cast(str, prompt)},
],
},
)

match infernet_input:
case InfernetInput(destination=JobLocation.OFFCHAIN):
"""
In case of an off-chain request, the result is returned as is.
"""
return {"message": result}
case InfernetInput(destination=JobLocation.ONCHAIN):
"""
In case of an on-chain request, the result is returned in the format:
# Ensure the request was successful, and get the result.
response.raise_for_status()
result = response.json()
content = result["choices"][0]["message"]["content"]

# Depending on the destination, the result is returned in a different format.
if onchain_destination:
"""
For on-chain requests, the result is returned in the format:
{
"raw_input": str,
"processed_input": str,
"raw_output": str,
"processed_output": str,
"proof": str,
}
refer to: https://docs.ritual.net/infernet/node/containers for more
info.
"""
return {
"raw_input": "",
"processed_input": "",
"raw_output": encode(["string"], [result]).hex(),
"processed_output": "",
"proof": "",
}
case _:
raise ValueError("Invalid destination")
refer to: https://docs.ritual.net/infernet/node/advanced/containers for more
info.
"""
return {
"raw_input": "",
"processed_input": "",
"raw_output": encode(["string"], [content]).hex(),
"processed_output": "",
"proof": "",
}
else:
"""
For off-chain request, the result is returned as is.
"""
return {"message": content}

return app

Expand Down
4 changes: 0 additions & 4 deletions projects/gpt4/container/src/requirements.txt

This file was deleted.

2 changes: 1 addition & 1 deletion projects/gpt4/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This is a minimalist foundry project that implements a [callback consumer](https://docs.ritual.net/infernet/sdk/consumers/Callback)
that makes a prompt to the [container](../container/README.md), which then makes a call to OpenAI's GPT4. For an
end-to-end flow of how this works, follow the [guide here](../gpt4.md).
end-to-end flow of how this works, follow our [GPT4 tutorial](https://learn.ritual.net/examples/running_gpt_4).

## Deploying

Expand Down
Loading

0 comments on commit 5bdf085

Please sign in to comment.