From 3607c568de186bf6e226f077b460fcdd3901f327 Mon Sep 17 00:00:00 2001 From: Guillermo Rodriguez Date: Sat, 27 May 2023 17:50:47 -0300 Subject: [PATCH] Drop separate reqs file for tests Update docker containers Create cli helpers for interacting with skynet Add test Begin adding hyperion api to telegram frontend --- docker/Dockerfile.runtime | 5 +- docker/Dockerfile.runtime+cuda | 10 +-- requirements.test.txt | 6 -- requirements.txt | 6 +- skynet/cli.py | 150 +++++++++++++++++++++++++++------ skynet/frontend/telegram.py | 3 +- skynet/nodeos.py | 44 ++++++++-- tests/test_deploy.py | 43 ++++++++++ 8 files changed, 214 insertions(+), 53 deletions(-) delete mode 100644 requirements.test.txt diff --git a/docker/Dockerfile.runtime b/docker/Dockerfile.runtime index 7f09a6e..316fdcb 100644 --- a/docker/Dockerfile.runtime +++ b/docker/Dockerfile.runtime @@ -4,7 +4,6 @@ env DEBIAN_FRONTEND=noninteractive workdir /skynet -copy requirements.test.txt requirements.test.txt copy requirements.txt requirements.txt copy pytest.ini ./ copy setup.py ./ @@ -12,8 +11,6 @@ copy skynet ./skynet run pip install \ -e . \ - -r requirements.txt \ - -r requirements.test.txt + -r requirements.txt -copy scripts ./ copy tests ./ diff --git a/docker/Dockerfile.runtime+cuda b/docker/Dockerfile.runtime+cuda index 27a5a66..6d52960 100644 --- a/docker/Dockerfile.runtime+cuda +++ b/docker/Dockerfile.runtime+cuda @@ -1,5 +1,5 @@ from nvidia/cuda:11.7.0-devel-ubuntu20.04 -from python:3.10.0 +from python:3.11 env DEBIAN_FRONTEND=noninteractive @@ -15,21 +15,15 @@ run pip install -v -r requirements.cuda.0.txt run pip install -v -r requirements.cuda.1.txt run pip install -v -r requirements.cuda.2.txt -copy requirements.test.txt requirements.test.txt copy requirements.txt requirements.txt copy pytest.ini pytest.ini copy setup.py setup.py copy skynet skynet -run pip install -e . \ - -r requirements.txt \ - -r requirements.test.txt +run pip install -e . -r requirements.txt env PYTORCH_CUDA_ALLOC_CONF max_split_size_mb:128 env NVIDIA_VISIBLE_DEVICES=all env HF_HOME /hf_home -copy scripts scripts copy tests tests - -expose 40000-45000 diff --git a/requirements.test.txt b/requirements.test.txt deleted file mode 100644 index a35f4d3..0000000 --- a/requirements.test.txt +++ /dev/null @@ -1,6 +0,0 @@ -pdbpp -pytest -docker -psycopg2-binary - -git+https://github.com/guilledk/py-leap.git@async_net_requests#egg=py-eosio diff --git a/requirements.txt b/requirements.txt index 3fa199a..b6f2e30 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,13 @@ trio asks numpy +pdbpp Pillow triopg +pytest +docker aiohttp +psycopg2-binary pyTelegramBotAPI -git+https://github.com/goodboy/tractor.git@master#egg=tractor +py-leap@git+https://github.com/guilledk/py-leap.git@v0.1a11 diff --git a/skynet/cli.py b/skynet/cli.py index 28c4eb0..34c8619 100644 --- a/skynet/cli.py +++ b/skynet/cli.py @@ -1,6 +1,4 @@ #!/usr/bin/python -import importlib.util -torch_enabled = importlib.util.find_spec('torch') != None import os import json @@ -13,17 +11,14 @@ import trio import click import docker import asyncio +import requests from leap.cleos import CLEOS, default_nodeos_image -from leap.sugar import get_container - -if torch_enabled: - from . import utils - from .dgpu import open_dgpu_node +from leap.sugar import get_container, collect_stdout from .db import open_new_database from .config import * -from .nodeos import open_nodeos +from .nodeos import open_cleos, open_nodeos from .constants import ALGOS from .frontend.telegram import run_skynet_telegram @@ -44,6 +39,7 @@ def skynet(*args, **kwargs): @click.option('--steps', '-s', default=26) @click.option('--seed', '-S', default=None) def txt2img(*args, **kwargs): + from . import utils _, hf_token, _, cfg = init_env_from_config() utils.txt2img(hf_token, **kwargs) @@ -58,6 +54,7 @@ def txt2img(*args, **kwargs): @click.option('--steps', '-s', default=26) @click.option('--seed', '-S', default=None) def img2img(model, prompt, input, output, strength, guidance, steps, seed): + from . import utils _, hf_token, _, cfg = init_env_from_config() utils.img2img( hf_token, @@ -76,6 +73,7 @@ def img2img(model, prompt, input, output, strength, guidance, steps, seed): @click.option('--output', '-o', default='output.png') @click.option('--model', '-m', default='weights/RealESRGAN_x4plus.pth') def upscale(input, output, model): + from . import utils utils.upscale( img_path=input, output=output, @@ -84,9 +82,104 @@ def upscale(input, output, model): @skynet.command() def download(): + from . import utils _, hf_token, _, cfg = init_env_from_config() utils.download_all_models(hf_token) +@skynet.command() +@click.option( + '--account', '-a', default='telegram1') +@click.option( + '--permission', '-p', default='active') +@click.option( + '--key', '-k', default=None) +@click.option( + '--node-url', '-n', default='http://skynet.ancap.tech') +@click.option('--algo', '-a', default='midj') +@click.option( + '--prompt', '-p', default='a red old tractor in a sunny wheat field') +@click.option('--output', '-o', default='output.png') +@click.option('--width', '-w', default=512) +@click.option('--height', '-h', default=512) +@click.option('--guidance', '-g', default=10) +@click.option('--step', '-s', default=26) +@click.option('--seed', '-S', default=420) +@click.option('--upscaler', '-U', default='x4') +def enqueue( + account: str, + permission: str, + key: str | None, + node_url: str, + **kwargs +): + with open_cleos(node_url, key=key) as cleos: + req = json.dumps({ + 'method': 'diffuse', + 'params': kwargs + }) + binary = '' + + ec, out = cleos.push_action( + 'telos.gpu', 'enqueue', [account, req, binary], f'{account}@{permission}' + ) + + assert ec == 0 + print(collect_stdout(out)) + + +@skynet.command() +@click.option( + '--node-url', '-n', default='http://skynet.ancap.tech') +def queue(node_url: str): + resp = requests.post( + f'{node_url}/v1/chain/get_table_rows', + json={ + 'code': 'telos.gpu', + 'table': 'queue', + 'scope': 'telos.gpu', + 'json': True + } + ) + print(json.dumps(resp.json(), indent=4)) + +@skynet.command() +@click.option( + '--node-url', '-n', default='http://skynet.ancap.tech') +@click.argument('request-id') +def status(node_url: str, request_id: int): + resp = requests.post( + f'{node_url}/v1/chain/get_table_rows', + json={ + 'code': 'telos.gpu', + 'table': 'status', + 'scope': request_id, + 'json': True + } + ) + print(json.dumps(resp.json(), indent=4)) + +@skynet.command() +@click.option( + '--account', '-a', default='telegram1') +@click.option( + '--permission', '-p', default='active') +@click.option( + '--key', '-k', default=None) +@click.option( + '--node-url', '-n', default='http://skynet.ancap.tech') +@click.argument('request-id') +def dequeue( + account: str, + permission: str, + key: str | None, + node_url: str, + request_id: int +): + with open_cleos(node_url, key=key) as cleos: + ec, out = cleos.push_action( + 'telos.gpu', 'dequeue', [account, request_id], f'{account}@{permission}' + ) + assert ec == 0 @skynet.group() def run(*args, **kwargs): @@ -114,7 +207,7 @@ def nodeos(): @click.option( '--key', '-k', default=None) @click.option( - '--node-url', '-n', default='http://test1.us.telos.net:42000') + '--node-url', '-n', default='http://skynet.ancap.tech') @click.option( '--algos', '-A', default=json.dumps(['midj'])) def dgpu( @@ -125,25 +218,30 @@ def dgpu( node_url: str, algos: list[str] ): - dclient = docker.from_env() - vtestnet = get_container( - dclient, - default_nodeos_image(), - force_unique=True, - detach=True, - network='host', - remove=True) + from .dgpu import open_dgpu_node + vtestnet = None + try: + dclient = docker.from_env() + vtestnet = get_container( + dclient, + default_nodeos_image(), + force_unique=True, + detach=True, + network='host', + remove=True) - cleos = CLEOS(dclient, vtestnet, url=node_url, remote=node_url) + cleos = CLEOS(dclient, vtestnet, url=node_url, remote=node_url) - trio.run( - partial( - open_dgpu_node, - account, permission, - cleos, key=key, initial_algos=json.loads(algos) - )) + trio.run( + partial( + open_dgpu_node, + account, permission, + cleos, key=key, initial_algos=json.loads(algos) + )) - vtestnet.stop() + finally: + if vtestnet: + vtestnet.stop() @run.command() @@ -155,7 +253,7 @@ def dgpu( @click.option( '--key', '-k', default=None) @click.option( - '--node-url', '-n', default='http://test1.us.telos.net:42000') + '--node-url', '-n', default='http://skynet.ancap.tech') @click.option( '--db-host', '-h', default='localhost:5432') @click.option( diff --git a/skynet/frontend/telegram.py b/skynet/frontend/telegram.py index 2f47433..9f3dc2a 100644 --- a/skynet/frontend/telegram.py +++ b/skynet/frontend/telegram.py @@ -12,6 +12,7 @@ import docker from PIL import Image from leap.cleos import CLEOS, default_nodeos_image from leap.sugar import get_container, collect_stdout +from leap.hyperion import HyperionAPI from trio_asyncio import aio_as_trio from telebot.types import ( InputFile, InputMediaPhoto, InlineKeyboardButton, InlineKeyboardMarkup @@ -53,7 +54,6 @@ def prepare_metainfo_caption(tguser, meta: dict) -> str: meta_str += f'algo: \"{meta["algo"]}\"\n' if meta['upscaler']: meta_str += f'upscaler: \"{meta["upscaler"]}\"\n' - meta_str += f'sampler: k_euler_ancestral\n' meta_str += f'skynet v{VERSION}' return meta_str @@ -78,6 +78,7 @@ async def run_skynet_telegram( remove=True) cleos = CLEOS(dclient, vtestnet, url=node_url, remote=node_url) + hyperion = HyperionAPI(node_url) logging.basicConfig(level=logging.INFO) diff --git a/skynet/nodeos.py b/skynet/nodeos.py index e5089e9..6ddd51f 100644 --- a/skynet/nodeos.py +++ b/skynet/nodeos.py @@ -7,8 +7,38 @@ from contextlib import contextmanager as cm import docker -from leap.cleos import CLEOS -from leap.sugar import get_container, Symbol +from leap.cleos import CLEOS, default_nodeos_image +from leap.sugar import get_container, Symbol, random_string + + +@cm +def open_cleos( + node_url: str, + key: str | None +): + vtestnet = None + try: + dclient = docker.from_env() + vtestnet = get_container( + dclient, + default_nodeos_image(), + name=f'skynet-wallet-{random_string(size=8)}', + force_unique=True, + detach=True, + network='host', + remove=True) + + cleos = CLEOS(dclient, vtestnet, url=node_url, remote=node_url) + + if key: + cleos.setup_wallet(key) + + yield cleos + + finally: + if vtestnet: + vtestnet.stop() + @cm @@ -17,6 +47,7 @@ def open_nodeos(cleanup: bool = True): vtestnet = get_container( dclient, 'guilledk/py-eosio:leap-skynet-4.0.0', + name='skynet-nodeos', force_unique=True, detach=True, network='host') @@ -38,20 +69,19 @@ def open_nodeos(cleanup: bool = True): time.sleep(0.5) + public_dev_key = 'EOS5fLreY5Zq5owBhmNJTgQaLqQ4ufzXSTpStQakEyfxNFuUEgNs1' cleos.setup_wallet('5JnvSc6pewpHHuUHwvbJopsew6AKwiGnexwDRc2Pj2tbdw6iML9') cleos.wait_blocks(1) cleos.boot_sequence(token_sym=Symbol('GPU', 4)) - cleos.new_account('telos.gpu', ram=300000) + cleos.new_account('telos.gpu', ram=300000, key=public_dev_key) for i in range(1, 4): cleos.create_account_staked( - 'eosio', f'testworker{i}', - key='EOS5fLreY5Zq5owBhmNJTgQaLqQ4ufzXSTpStQakEyfxNFuUEgNs1') + 'eosio', f'testworker{i}', key=public_dev_key) cleos.create_account_staked( - 'eosio', 'telegram1', ram=500000, - key='EOS5fLreY5Zq5owBhmNJTgQaLqQ4ufzXSTpStQakEyfxNFuUEgNs1') + 'eosio', 'telegram1', ram=500000, key=public_dev_key) cleos.deploy_contract_from_host( 'telos.gpu', diff --git a/tests/test_deploy.py b/tests/test_deploy.py index 2bea848..17e1a15 100644 --- a/tests/test_deploy.py +++ b/tests/test_deploy.py @@ -11,6 +11,8 @@ import requests from skynet.dgpu import open_dgpu_node +from leap.sugar import collect_stdout + def test_enqueue_work(cleos): @@ -79,3 +81,44 @@ def test_enqueue_work(cleos): assert resp.status_code == 200 assert sha_hash == sha256(resp.content).hexdigest() + + +def test_enqueue_dequeue(cleos): + + user = cleos.new_account() + req = json.dumps({ + 'method': 'diffuse', + 'params': { + 'algo': 'midj', + 'prompt': 'skynet terminator dystopic', + 'width': 512, + 'height': 512, + 'guidance': 10, + 'step': 28, + 'seed': 420, + 'upscaler': 'x4' + } + }) + binary = '' + + ec, out = cleos.push_action( + 'telos.gpu', 'enqueue', [user, req, binary], f'{user}@active' + ) + + assert ec == 0 + + request_id = int(collect_stdout(out)) + + queue = cleos.get_table('telos.gpu', 'telos.gpu', 'queue') + + assert len(queue) == 1 + + ec, out = cleos.push_action( + 'telos.gpu', 'dequeue', [user, request_id], f'{user}@active' + ) + + assert ec == 0 + + queue = cleos.get_table('telos.gpu', 'telos.gpu', 'queue') + + assert len(queue) == 0