opengradient 0.3.1__py3-none-any.whl → 0.3.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- opengradient/__init__.py +11 -2
- opengradient/cli.py +44 -3
- opengradient/client.py +98 -6
- {opengradient-0.3.1.dist-info → opengradient-0.3.3.dist-info}/METADATA +6 -1
- {opengradient-0.3.1.dist-info → opengradient-0.3.3.dist-info}/RECORD +9 -9
- {opengradient-0.3.1.dist-info → opengradient-0.3.3.dist-info}/LICENSE +0 -0
- {opengradient-0.3.1.dist-info → opengradient-0.3.3.dist-info}/WHEEL +0 -0
- {opengradient-0.3.1.dist-info → opengradient-0.3.3.dist-info}/entry_points.txt +0 -0
- {opengradient-0.3.1.dist-info → opengradient-0.3.3.dist-info}/top_level.txt +0 -0
opengradient/__init__.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from .client import Client
|
|
2
2
|
from .defaults import *
|
|
3
3
|
from .types import InferenceMode
|
|
4
|
-
from typing import List, Dict
|
|
5
|
-
__version__ = "0.3.
|
|
4
|
+
from typing import List, Dict, Optional, Tuple
|
|
5
|
+
__version__ = "0.3.3"
|
|
6
6
|
|
|
7
7
|
_client = None
|
|
8
8
|
|
|
@@ -42,6 +42,15 @@ def infer(model_cid, inference_mode, model_input):
|
|
|
42
42
|
raise RuntimeError("OpenGradient client not initialized. Call og.init() first.")
|
|
43
43
|
return _client.infer(model_cid, inference_mode, model_input)
|
|
44
44
|
|
|
45
|
+
def infer_llm(model_cid: str,
|
|
46
|
+
prompt: str,
|
|
47
|
+
max_tokens: int = 100,
|
|
48
|
+
stop_sequence: Optional[List[str]] = None,
|
|
49
|
+
temperature: float = 0.0) -> Tuple[str, str]:
|
|
50
|
+
if _client is None:
|
|
51
|
+
raise RuntimeError("OpenGradient client not initialized. Call og.init() first.")
|
|
52
|
+
return _client.infer_llm(model_cid, prompt, max_tokens, stop_sequence, temperature)
|
|
53
|
+
|
|
45
54
|
def login(email: str, password: str):
|
|
46
55
|
if _client is None:
|
|
47
56
|
raise RuntimeError("OpenGradient client not initialized. Call og.init() first.")
|
opengradient/cli.py
CHANGED
|
@@ -5,6 +5,7 @@ import ast
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
import logging
|
|
7
7
|
from pprint import pformat
|
|
8
|
+
from typing import List
|
|
8
9
|
import webbrowser
|
|
9
10
|
import sys
|
|
10
11
|
|
|
@@ -97,7 +98,13 @@ def initialize_config(ctx):
|
|
|
97
98
|
@click.group()
|
|
98
99
|
@click.pass_context
|
|
99
100
|
def cli(ctx):
|
|
100
|
-
"""
|
|
101
|
+
"""
|
|
102
|
+
CLI for OpenGradient SDK.
|
|
103
|
+
|
|
104
|
+
Run 'opengradient config show' to make sure you have configs set up.
|
|
105
|
+
|
|
106
|
+
Visit https://docs.opengradient.ai/developers/python_sdk/ for more documentation.
|
|
107
|
+
"""
|
|
101
108
|
# Load existing config
|
|
102
109
|
ctx.obj = load_og_config()
|
|
103
110
|
|
|
@@ -149,7 +156,7 @@ def show(ctx):
|
|
|
149
156
|
click.echo("Current config:")
|
|
150
157
|
for key, value in ctx.obj.items():
|
|
151
158
|
if key != 'client': # Don't display the client object
|
|
152
|
-
if key == 'password' and value is not None:
|
|
159
|
+
if (key == 'password' or key == 'private_key') and value is not None:
|
|
153
160
|
click.echo(f"{key}: {'*' * len(value)}") # Mask the password
|
|
154
161
|
elif value is None:
|
|
155
162
|
click.echo(f"{key}: Not set")
|
|
@@ -294,7 +301,6 @@ def infer(ctx, model_cid: str, inference_mode: str, input_data, input_file: Path
|
|
|
294
301
|
with input_file.open('r') as file:
|
|
295
302
|
model_input = json.load(file)
|
|
296
303
|
|
|
297
|
-
# Parse input data from string to dict
|
|
298
304
|
click.echo(f"Running {inference_mode} inference for model \"{model_cid}\"\n")
|
|
299
305
|
tx_hash, model_output = client.infer(model_cid=model_cid, inference_mode=InferenceModes[inference_mode], model_input=model_input)
|
|
300
306
|
|
|
@@ -307,6 +313,41 @@ def infer(ctx, model_cid: str, inference_mode: str, input_data, input_file: Path
|
|
|
307
313
|
except Exception as e:
|
|
308
314
|
click.echo(f"Error running inference: {str(e)}")
|
|
309
315
|
|
|
316
|
+
@cli.command()
|
|
317
|
+
@click.option('--model', '-m', 'model_cid', required=True, help='CID of the LLM model to run inference on')
|
|
318
|
+
@click.option('--prompt', '-p', required=True, help='Input prompt for the LLM')
|
|
319
|
+
@click.option('--max-tokens', type=int, default=100, help='Maximum number of tokens for LLM output')
|
|
320
|
+
@click.option('--stop-sequence', multiple=True, help='Stop sequences for LLM')
|
|
321
|
+
@click.option('--temperature', type=float, default=0.0, help='Temperature for LLM inference (0.0 to 1.0)')
|
|
322
|
+
@click.pass_context
|
|
323
|
+
def llm(ctx, model_cid: str, prompt: str, max_tokens: int, stop_sequence: List[str], temperature: float):
|
|
324
|
+
"""
|
|
325
|
+
Run inference on an LLM model.
|
|
326
|
+
|
|
327
|
+
This command runs inference on the specified LLM model using the provided prompt and parameters.
|
|
328
|
+
|
|
329
|
+
Example usage:
|
|
330
|
+
|
|
331
|
+
\b
|
|
332
|
+
opengradient llm --model Qm... --prompt "Hello, how are you?" --max-tokens 50 --temperature 0.7
|
|
333
|
+
opengradient llm -m Qm... -p "Translate to French: Hello world" --stop-sequence "." --stop-sequence "\n"
|
|
334
|
+
"""
|
|
335
|
+
client: Client = ctx.obj['client']
|
|
336
|
+
try:
|
|
337
|
+
click.echo(f"Running LLM inference for model \"{model_cid}\"\n")
|
|
338
|
+
tx_hash, llm_output = client.infer_llm(
|
|
339
|
+
model_cid=model_cid,
|
|
340
|
+
prompt=prompt,
|
|
341
|
+
max_tokens=max_tokens,
|
|
342
|
+
stop_sequence=list(stop_sequence),
|
|
343
|
+
temperature=temperature
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
click.secho("Success!", fg="green")
|
|
347
|
+
click.echo(f"Transaction hash: {tx_hash}")
|
|
348
|
+
click.echo(f"LLM output:\n{llm_output}")
|
|
349
|
+
except Exception as e:
|
|
350
|
+
click.echo(f"Error running LLM inference: {str(e)}")
|
|
310
351
|
|
|
311
352
|
@cli.command()
|
|
312
353
|
def create_account():
|
opengradient/client.py
CHANGED
|
@@ -7,7 +7,7 @@ from opengradient.types import InferenceMode
|
|
|
7
7
|
from opengradient import utils
|
|
8
8
|
import numpy as np
|
|
9
9
|
import logging
|
|
10
|
-
from typing import Dict, Tuple, Union, List
|
|
10
|
+
from typing import Dict, Optional, Tuple, Union, List
|
|
11
11
|
from web3.exceptions import ContractLogicError
|
|
12
12
|
import firebase
|
|
13
13
|
|
|
@@ -58,6 +58,14 @@ class Client:
|
|
|
58
58
|
if email is not None:
|
|
59
59
|
self.login(email, password)
|
|
60
60
|
|
|
61
|
+
def login(self, email, password):
|
|
62
|
+
try:
|
|
63
|
+
self.user = self.auth.sign_in_with_email_and_password(email, password)
|
|
64
|
+
return self.user
|
|
65
|
+
except Exception as e:
|
|
66
|
+
logging.error(f"Authentication failed: {str(e)}")
|
|
67
|
+
raise
|
|
68
|
+
|
|
61
69
|
def _initialize_web3(self):
|
|
62
70
|
"""
|
|
63
71
|
Initialize the Web3 instance if it is not already initialized.
|
|
@@ -402,13 +410,97 @@ class Client:
|
|
|
402
410
|
logging.error(f"Error in infer method: {str(e)}", exc_info=True)
|
|
403
411
|
raise OpenGradientError(f"Inference failed: {str(e)}")
|
|
404
412
|
|
|
405
|
-
def
|
|
413
|
+
def infer_llm(self,
|
|
414
|
+
model_cid: str,
|
|
415
|
+
prompt: str,
|
|
416
|
+
max_tokens: int = 100,
|
|
417
|
+
stop_sequence: Optional[List[str]] = None,
|
|
418
|
+
temperature: float = 0.0) -> Tuple[str, str]:
|
|
419
|
+
"""
|
|
420
|
+
Perform inference on an LLM model using completions.
|
|
421
|
+
|
|
422
|
+
Args:
|
|
423
|
+
model_cid (str): The unique content identifier for the model.
|
|
424
|
+
prompt (str): The input prompt for the LLM.
|
|
425
|
+
max_tokens (int): Maximum number of tokens for LLM output. Default is 100.
|
|
426
|
+
stop_sequence (List[str], optional): List of stop sequences for LLM. Default is None.
|
|
427
|
+
temperature (float): Temperature for LLM inference, between 0 and 1. Default is 0.0.
|
|
428
|
+
|
|
429
|
+
Returns:
|
|
430
|
+
Tuple[str, str]: The transaction hash and the LLM output.
|
|
431
|
+
|
|
432
|
+
Raises:
|
|
433
|
+
OpenGradientError: If the inference fails.
|
|
434
|
+
"""
|
|
406
435
|
try:
|
|
407
|
-
self.
|
|
408
|
-
|
|
436
|
+
self._initialize_web3()
|
|
437
|
+
|
|
438
|
+
abi_path = os.path.join(os.path.dirname(__file__), 'abi', 'llm.abi')
|
|
439
|
+
with open(abi_path, 'r') as abi_file:
|
|
440
|
+
llm_abi = json.load(abi_file)
|
|
441
|
+
contract = self._w3.eth.contract(address=self.contract_address, abi=llm_abi)
|
|
442
|
+
|
|
443
|
+
# Prepare LLM input
|
|
444
|
+
llm_request = {
|
|
445
|
+
"mode": InferenceMode.VANILLA,
|
|
446
|
+
"modelCID": model_cid,
|
|
447
|
+
"prompt": prompt,
|
|
448
|
+
"max_tokens": max_tokens,
|
|
449
|
+
"stop_sequence": stop_sequence or [],
|
|
450
|
+
"temperature": int(temperature * 100) # Scale to 0-100 range
|
|
451
|
+
}
|
|
452
|
+
logging.debug(f"Prepared LLM request: {llm_request}")
|
|
453
|
+
|
|
454
|
+
# Prepare run function
|
|
455
|
+
run_function = contract.functions.runLLM(llm_request)
|
|
456
|
+
|
|
457
|
+
# Build transaction
|
|
458
|
+
nonce = self._w3.eth.get_transaction_count(self.wallet_address)
|
|
459
|
+
estimated_gas = run_function.estimate_gas({'from': self.wallet_address})
|
|
460
|
+
gas_limit = int(estimated_gas * 1.2)
|
|
461
|
+
|
|
462
|
+
transaction = run_function.build_transaction({
|
|
463
|
+
'from': self.wallet_address,
|
|
464
|
+
'nonce': nonce,
|
|
465
|
+
'gas': gas_limit,
|
|
466
|
+
'gasPrice': self._w3.eth.gas_price,
|
|
467
|
+
})
|
|
468
|
+
|
|
469
|
+
# Sign and send transaction
|
|
470
|
+
signed_tx = self._w3.eth.account.sign_transaction(transaction, self.private_key)
|
|
471
|
+
tx_hash = self._w3.eth.send_raw_transaction(signed_tx.raw_transaction)
|
|
472
|
+
logging.debug(f"Transaction sent. Hash: {tx_hash.hex()}")
|
|
473
|
+
|
|
474
|
+
# Wait for transaction receipt
|
|
475
|
+
tx_receipt = self._w3.eth.wait_for_transaction_receipt(tx_hash)
|
|
476
|
+
|
|
477
|
+
if tx_receipt['status'] == 0:
|
|
478
|
+
raise ContractLogicError(f"Transaction failed. Receipt: {tx_receipt}")
|
|
479
|
+
|
|
480
|
+
# Process the LLMResult event
|
|
481
|
+
llm_result = None
|
|
482
|
+
for log in tx_receipt['logs']:
|
|
483
|
+
try:
|
|
484
|
+
decoded_log = contract.events.LLMResult().process_log(log)
|
|
485
|
+
llm_result = decoded_log['args']['response']['answer']
|
|
486
|
+
break
|
|
487
|
+
except:
|
|
488
|
+
continue
|
|
489
|
+
|
|
490
|
+
if llm_result is None:
|
|
491
|
+
raise OpenGradientError("LLMResult event not found in transaction logs")
|
|
492
|
+
|
|
493
|
+
logging.debug(f"LLM output: {llm_result}")
|
|
494
|
+
|
|
495
|
+
return tx_hash.hex(), llm_result
|
|
496
|
+
|
|
497
|
+
except ContractLogicError as e:
|
|
498
|
+
logging.error(f"Contract logic error: {str(e)}", exc_info=True)
|
|
499
|
+
raise OpenGradientError(f"LLM inference failed due to contract logic error: {str(e)}")
|
|
409
500
|
except Exception as e:
|
|
410
|
-
logging.error(f"
|
|
411
|
-
raise
|
|
501
|
+
logging.error(f"Error in infer_llm method: {str(e)}", exc_info=True)
|
|
502
|
+
raise OpenGradientError(f"LLM inference failed: {str(e)}")
|
|
503
|
+
|
|
412
504
|
|
|
413
505
|
def list_files(self, model_name: str, version: str) -> List[Dict]:
|
|
414
506
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: opengradient
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Python SDK for OpenGradient decentralized model management & inference services
|
|
5
5
|
Author-email: OpenGradient <oliver@opengradient.ai>
|
|
6
6
|
License: MIT License
|
|
@@ -227,4 +227,9 @@ opengradient infer QmbUqS93oc4JTLMHwpVxsE39mhNxy6hpf6Py3r9oANr8aZ VANILLA '{"num
|
|
|
227
227
|
opengradient infer QmbUqS93oc4JTLMHwpVxsE39mhNxy6hpf6Py3r9oANr8aZ VANILLA --input_file input.json
|
|
228
228
|
```
|
|
229
229
|
|
|
230
|
+
#### Run LLM Inference
|
|
231
|
+
```bash
|
|
232
|
+
opengradient llm --model "meta-llama/Meta-Llama-3-8B-Instruct" --prompt "Translate to French: Hello, how are you?" --max-tokens 50 --temperature 0.7
|
|
233
|
+
```
|
|
234
|
+
|
|
230
235
|
For more information read the OpenGradient [documentation](https://docs.opengradient.ai/).
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
opengradient/__init__.py,sha256=
|
|
1
|
+
opengradient/__init__.py,sha256=91_tgWyaYIeOUxbE6h3F1IreQbFd9-zuRft3rnsgylY,2447
|
|
2
2
|
opengradient/account.py,sha256=s1C4hAtc8vcHObWjwxwlYJA041S6DTbr7-rK6qiWPsQ,1149
|
|
3
|
-
opengradient/cli.py,sha256=
|
|
4
|
-
opengradient/client.py,sha256=
|
|
3
|
+
opengradient/cli.py,sha256=T59Z2S3AsMVS6TLgsSgxW9esssvYP5ZmVJrYE6p4oW4,16105
|
|
4
|
+
opengradient/client.py,sha256=DCDp2EWPF62ZQnx2_cM0wPghRxgn213VnR65R8yZBVY,23964
|
|
5
5
|
opengradient/defaults.py,sha256=pDfsmPoUzdLG55n-hwh0CMBFxKR2rdNcjqCcwTWc6iw,267
|
|
6
6
|
opengradient/exceptions.py,sha256=v4VmUGTvvtjhCZAhR24Ga42z3q-DzR1Y5zSqP_yn2Xk,3366
|
|
7
7
|
opengradient/types.py,sha256=EoJN-DkQrJ2WTUv8OenlrlWJWFY2jPGTl-T8C_OVjp8,1849
|
|
8
8
|
opengradient/utils.py,sha256=F1Nj-GMNFQFxCtbGgWQq1RP4TSurbpQxJV3yKeEo1b0,6482
|
|
9
9
|
opengradient/abi/inference.abi,sha256=u8FsW0s1YeRjUb9eLS1k_qh_5f_cwOdr0bii-tAdxh0,2683
|
|
10
10
|
opengradient/abi/llm.abi,sha256=zhiPFyBT09EI3QU5DVoKHo7e8T9PFcfIQ3RHDYetm4M,3609
|
|
11
|
-
opengradient-0.3.
|
|
12
|
-
opengradient-0.3.
|
|
13
|
-
opengradient-0.3.
|
|
14
|
-
opengradient-0.3.
|
|
15
|
-
opengradient-0.3.
|
|
16
|
-
opengradient-0.3.
|
|
11
|
+
opengradient-0.3.3.dist-info/LICENSE,sha256=xEcvQ3AxZOtDkrqkys2Mm6Y9diEnaSeQRKvxi-JGnNA,1069
|
|
12
|
+
opengradient-0.3.3.dist-info/METADATA,sha256=80TVQCE8tC5JX7ZuFdqXu5IdFbuCmo5hi1g96eGrCQA,7805
|
|
13
|
+
opengradient-0.3.3.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
14
|
+
opengradient-0.3.3.dist-info/entry_points.txt,sha256=yUKTaJx8RXnybkob0J62wVBiCp_1agVbgw9uzsmaeJc,54
|
|
15
|
+
opengradient-0.3.3.dist-info/top_level.txt,sha256=oC1zimVLa2Yi1LQz8c7x-0IQm92milb5ax8gHBHwDqU,13
|
|
16
|
+
opengradient-0.3.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|