diff --git a/README.md b/README.md index 6ded9648..db94fc60 100644 --- a/README.md +++ b/README.md @@ -1 +1,46 @@ -# atoma-node +# Atoma Node infrastructure + +## Introduction + +The present repository contains the logic to run an Atoma node. Atoma nodes empower the Atoma Network, a decentralized network +for verifiable AI inference. Nodes can lend their GPU compute to the protocol, so large language models (LLMs for short) can be +run across a decentralized network, at a cheaper cost. Moreover, nodes can be organized in order to provide verifiability guarantees +of the correctness of their generated outputs. This means that the Atoma Network can empower smart contracts, deployed on any blockchain, +to run verifiable inference and guarantee an intelligence layer to Web3. + +## Run a node + +In order to run an Atoma node, you should provide enough evidence of holding a powerful enough machine for AI inference. We +allow a wide range of possible hardware, including NVIDIA GPU series (RTX3090, RTX4090, A100, etc), as well as a good enough +Internet bandwidth connection. We further highly encourage nodes to register on Atoma contracts on supported blockchains +(these include Arbitrum, Solana, Sui, etc). In order to register, we suggest the reader to follow the instructions in the +Atoma contract [repo](https://github.com/atoma-network/atoma-contracts). + +Once registration has been completed, the user is required to: + +1. Clone this repo (it is assumed that Rust is installed, otherwise follow the instructions [here](https://www.rust-lang.org/tools/install)). +2. Create configuration files for both the model inference service, the event listener service and the blockchain client service. Notice +that the event listener and blockchain client services need to be for the same blockchain, in which the node has previously registered. That said, a single node can be registered in multiple blockchains and listen to events on each of these (for higher accrued rewards). +3. The model inference service follows schematically (in toml format): + +```toml +api_key = "" # for downloading models +cache_dir = "" # where you want the downloaded models to be stored +flush_storage = true # when the user stops the Atoma node, it flushes or not the downloaded models +jrpc_port = 3000 # Atoma node JRPC port +models = [[device, precision, model_type, revision, use_flash_attention], ...] # Specifications for each model the user wants to operate, as an Atoma Node +tracing = true # Allows for tracing +``` +4. The event subscriber service configuration file is specified as (in toml format): + +```toml +http_url = "RPC_NODE_HTTP_URL" # to connect via http to a rpc node on the blockchain +ws_url = "RPC_NODE_WEB_SOCKET_URL" # to connect via web socket to a rpc node on the blockchain, relevant for listening to events +package_id = "SUI_PACKAGE_ID" # the Atoma contract object id, on Sui. +small_id = 28972375 # a unique identifier provided to the node, upon on-chain registration + +[request_timeout] # a request timeout parameter +secs = 300 +nanos = 0 + +``` \ No newline at end of file diff --git a/atoma-types/src/lib.rs b/atoma-types/src/lib.rs index 895e340f..ad0f6eb3 100644 --- a/atoma-types/src/lib.rs +++ b/atoma-types/src/lib.rs @@ -4,6 +4,14 @@ use serde_json::{json, Value}; pub type SmallId = u64; +/// Represents a request object containing information about a request +/// Prompt event, emitted on a given blockchain, see https://github.com/atoma-network/atoma-contracts/blob/main/sui/packages/atoma/sources/gate.move#L45. +/// It includes information about a ticket ID, sampled nodes, and request parameters. +/// +/// Fields: +/// id: Vec - The ticket ID associated with the request (or event). +/// sampled_nodes: Vec - A vector of sampled nodes, each represented by a SmallId structure. +/// body: serde_json::Value - JSON value containing request parameters. #[derive(Clone, Debug, Deserialize)] pub struct Request { #[serde(rename(deserialize = "ticket_id"))] @@ -61,6 +69,9 @@ impl TryFrom for Request { } } +/// Parses the body of a JSON value. This JSON value is supposed to be obtained +/// from a Sui `Text2TextPromptEvent`, +/// see https://github.com/atoma-network/atoma-contracts/blob/main/sui/packages/atoma/sources/gate.move#L28 fn parse_body(json: Value) -> Result { let output = json!({ "max_tokens": parse_u64(&json["max_tokens"])?, @@ -90,6 +101,8 @@ fn parse_f32_from_le_bytes(value: &Value) -> Result { Ok(f32::from_le_bytes(f32_le_bytes)) } +/// Parses an appropriate JSON value, representing a `u64` number, from a Sui +/// `Text2TextPromptEvent` `u64` fields. fn parse_u64(value: &Value) -> Result { value .as_str() @@ -98,6 +111,12 @@ fn parse_u64(value: &Value) -> Result { .map_err(|e| anyhow!("Failed to parse `u64` from string, with error: {e}")) } +/// Represents a response object containing information about a response, including an ID, sampled nodes, and the response data. +/// +/// Fields: +/// id: Vec - The ticket id associated with the request, that lead to the generation of this response. +/// sampled_nodes: Vec - A vector of sampled nodes, each represented by a SmallId structure. +/// response: serde_json::Value - JSON value containing the response data. #[derive(Debug)] pub struct Response { id: Vec,