return model inputs = { # 'file': file(extension=".zip"), 'image': image(), 'model': category(choices=["none", "random", "color", "bit/m-r101x1", "vgg16"], default="color", description='Cluster model.'), 'slices': number(min=5, max=30, step=5, default=10, description='Number of slices.'), 'vgg_depth': number(min=1, max=8, step=1, default=7, description='VGG Feature Depth'), } # Every model needs to have at least one command. Every command allows to send # inputs and process outputs. To see a complete list of supported inputs and # outputs data types: https://sdk.runwayml.com/en/latest/data_types.html @runway.command(name='generate', inputs=inputs, outputs={ 'image': image(width=512, height=512), 'info': text("hello") }, description='Generates a red square when the input text input is "red".') def generate(model, args): print('[GENERATE] Ran with image "{}"'.format(args['image'])) # Generate a PIL or Numpy image based on the input caption, and return it output_image = model.run_on_input(args['image'], args['slices'], args['model'], args['vgg_depth']) return { 'image': output_image['image'], 'info': output_image['info'] } if __name__ == '__main__': # run the model server using the default network interface and ports, # displayed here for convenience runway.run(host='0.0.0.0', port=9000) ## Now that the model is running, open a new terminal and give it a command to
classify_description = ("Classify give face image returning probabilities and " "most likely class\n Probabilities correspond to:" f" {', '.join(emotion_classifier.EMOTIONS)}") @runway.command('classify', inputs={'image': image(description="Cropped face image")}, outputs={ 'probabilities': vector(length=len(emotion_classifier.EMOTIONS), description="Probabilities of corresponding " "face being each possible class"), 'most_likely_class': text(description="Most likely class of face") }, description=classify_description) def classify(model, inputs): """Classify given face image. Returns probabilities of face's emotion classification and most likely class. probabilities correspond to emotion_classifier.EMOTIONS """ image = inputs['image'] gray_image = utils.grayscale_from_pil(image) probabilities = model.predict_emotions([gray_image])[0] most_likely_class = emotion_classifier.EMOTIONS[probabilities.argmax()] return {
@runway.setup(options=setup_options) def setup(opts): msg = '[SETUP] Ran with options: seed = {}, truncation = {}' print(msg.format(opts['seed'], opts['truncation'])) model = ExampleModel(opts) return model # Every model needs to have at least one command. Every command allows to send # inputs and process outputs. To see a complete list of supported inputs and # outputs data types: https://sdk.runwayml.com/en/latest/data_types.html @runway.command( name='generate', inputs={'caption': text()}, outputs={'image': image(width=512, height=512)}, description='Generates a red square when the input text input is "red".') def generate(model, args): print('[GENERATE] Ran with caption value "{}"'.format(args['caption'])) # Generate a PIL or Numpy image based on the input caption, and return it output_image = model.run_on_input(args['caption']) return {'image': output_image} @runway.command(name='add', inputs={ 'x': number('', 10, 10, 0, 200), 'y': number('', 40, 10, 0, 200), }, outputs={'addition': number()},
import runway from runway.data_types import text, number import gzip from markovify import Text @runway.setup def setup(): msg = '[SETUP]' with gzip.open('./novel-model-markovify.json.gz') as fh: return Text.from_json(fh.read()) @runway.command( name='generate', inputs={'max_len': number(default=80, min=10, max=1000), 'seed': number(default=0, min=0, max=1e6)}, outputs={'output': text()}) def generate(model, args): print('[GENERATE] Ran with max_len value "{}"'.format(args['max_len'])) output = model.make_short_sentence(args['max_len']) return {'output': output} if __name__ == '__main__': runway.run(host='0.0.0.0', port=8000)
# used. setup_options = { 'truncation': number(min=5, max=100, step=1, default=10), 'seed': number(min=0, max=1000000) } @runway.setup(options=setup_options) def setup(opts): msg = '[SETUP] Ran with options: seed = {}, truncation = {}' print(msg.format(opts['seed'], opts['truncation'])) model = ExampleModel(opts) return model # Every model needs to have at least one command. Every command allows to send # inputs and process outputs. To see a complete list of supported inputs and # outputs data types: https://sdk.runwayml.com/en/latest/data_types.html @runway.command(name='classify', inputs={'image': image(width=224, height=224)}, outputs={'class_name': text()}) def classify(model, args): # Generate a PIL or Numpy image based on the input caption, and return it class_name = model.classify(args['image']) return {'class_name': class_name} if __name__ == '__main__': # run the model server using the default network interface and ports, # displayed here for convenience runway.run(host='0.0.0.0', port=8000)
# Load model @runway.setup def setup(): return models.load_model(arch) # Get dataset categories categories = models.load_categories() # Load the video frame transform transform = models.load_transform() @runway.command('classify', inputs={'video': text()}, outputs={'label': text()}) def classify(model, input): yt = YouTube('https://youtube.com/embed/%s?start=%d&end=%d' % (input['video'], start, end)) video = yt.streams.all()[0] video_file = video.download(videoPath) num_segments = 16 print('Extracting frames using ffmpeg...') frames = extract_frames(video_file, num_segments) # Prepare input tensor input = torch.stack([transform(frame) for frame in frames], 1).unsqueeze(0)
def test_model_setup_and_command(): # use a dict to share state across function scopes. This makes up for the # fact that Python 2.x doesn't have support for the 'nonlocal' keyword. closure = dict(setup_ran=False, command_ran=False) expected_manifest = { 'modelSDKVersion': model_sdk_version, 'millisRunning': None, 'millisSinceLastCommand': None, 'GPU': os.environ.get('GPU', False), 'options': [{ 'type': 'category', 'name': 'size', 'oneOf': ['big', 'small'], 'default': 'big', 'description': 'The size of the model. Bigger is better but also slower.', }], 'commands': [{ 'name': 'test_command', 'description': None, 'inputs': [{ 'type': 'text', 'name': 'input', 'description': 'Some input text.', 'default': '', 'minLength': 0 }], 'outputs': [{ 'type': 'number', 'name': 'output', 'description': 'An output number.', 'default': 0 }] }] } rw = RunwayModel() description = 'The size of the model. Bigger is better but also slower.' @rw.setup(options={ 'size': category(choices=['big', 'small'], description=description) }) def setup(opts): closure['setup_ran'] = True return {} inputs = {'input': text(description='Some input text.')} outputs = {'output': number(description='An output number.')} # Python 2.7 doesn't seem to handle emoji serialization correctly in JSON, # so we will only test emoji serialization/deserialization in Python 3 if sys.version_info[0] < 3: description = 'Sorry, Python 2 doesn\'t support emoji very well' else: description = 'A test command whose description contains emoji 🕳' expected_manifest['commands'][0]['description'] = description @rw.command('test_command', inputs=inputs, outputs=outputs, description=description) def test_command(model, opts): closure['command_ran'] = True return 100 rw.run(debug=True) client = get_test_client(rw) response = client.get('/meta') assert response.is_json manifest = json.loads(response.data) # unset millisRunning as we can't reliably predict this value. # testing that it is an int should be good enough. assert type(manifest['millisRunning']) == int manifest['millisRunning'] = None assert manifest == expected_manifest # TEMPORARILY CHECK / PATH IN ADDITION TO /meta ---------------------------- # ... sorry for the gross dupe code ;) response = client.get('/') assert response.is_json manifest = json.loads(response.data) # unset millisRunning as we can't reliably predict this value. # testing that it is an int should be good enough. assert type(manifest['millisRunning']) == int manifest['millisRunning'] = None assert manifest == expected_manifest # -------------------------------------------------------------------------- # check the input/output manifest for GET /test_command response = client.get('/test_command') assert response.is_json command_manifest = json.loads(response.data) assert command_manifest == expected_manifest['commands'][0] post_data = {'input': 'test input'} response = client.post('/test_command', json=post_data) assert response.is_json assert json.loads(response.data) == {'output': 100} # now that we've run a command lets make sure millis since last command is # a number manifest_after_command = get_manifest(client) assert type(manifest_after_command['millisSinceLastCommand']) == int assert closure['command_ran'] == True assert closure['setup_ran'] == True
# Import the Runway SDK. Please install it first with # `pip install runway-python`. import runway from runway.data_types import number, text, image, vector from example_model import CPPNModel # Setup the model, initialize weights, set the configs of the model, etc. # Every model will have a different set of configurations and requirements. # Check https://docs.runwayapp.ai/#/python-sdk to see a complete list of # supported configs. The setup function should return the model ready to be # used. setup_options = { 'mode': text(default='tanh'), 'seed': number(min=0, max=1000000, default=5, description='A seed used to initialize the model.'), 'resolution': number(min=32, max=1024, default=64, description='output image size') } res = 64 @runway.setup(options=setup_options) def setup(opts): msg = '[SETUP] Ran with options: mode = {}, seed = {}, res = {}' print(msg.format(opts['mode'], opts['seed'], opts['resolution'])) res = opts['resolution'] model = CPPNModel(opts) return model
import runway import shutil import gpt_2_simple as gpt2 from runway.data_types import text # Setup the model, initialize weights, set the configs of the model, etc. # Every model will have a different set of configurations and requirements. # Check https://docs.runwayapp.ai/#/python-sdk to see a complete list of # supported configs. The setup function should return the model ready to be # used. setup_options = { 'run_name': text(default='first_345m_run'), 'checkpoint_file': runway.file(), } run_name = None sess = None @runway.setup(options=setup_options) def setup(opts): global run_name, sess run_name = opts['run_name'] print(f'Run name: {run_name}') shutil.copy(opts['checkpoint_file'], f'checkpoints/{run_name}/model-10000.data-00000-of-00001') sess = gpt2.start_tf_sess() gpt2.load_gpt2(sess, run_name=run_name) return None
def setup(): print('[SETUP] loading model...') model = UniSentenceEncXling() print('[SETUP] done.') return model desc = """\ Infers embeddings for input. Returns an array with the lines of text and an array with the corresponding embeddings for each line. """ @runway.command(name='embed', inputs={ 'text': text(), 'tokenize_sentences': boolean(default=True) }, outputs={ 'sentences': array(item_type=text), 'embeddings': array(item_type=vector(length=512)) }, description=desc) def embed(model, args): if args['tokenize_sentences']: sentences = sent_tokenize(args['text']) else: sentences = args['text'].split("\n") print('[EMBED] Embedding {} sentences'.format(len(sentences))) results = model.embed(sentences) return {'sentences': sentences, 'embeddings': results}
normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) preprocess = transforms.Compose([ transforms.Scale(256), transforms.CenterCrop(224), transforms.ToTensor(), normalize ]) @runway.setup def setup(): return models.squeezenet1_1(pretrained=True) @runway.command('classify', inputs={'photo': image()}, outputs={'label': text()}) def classify(model, input): img = input['photo'] img_tensor = preprocess(img) img_tensor.unsqueeze_(0) img_variable = Variable(img_tensor) fc_out = model(img_variable) label = labels[str(fc_out.data.numpy().argmax())] return {'label': label} if __name__ == '__main__': runway.run()
# RunwayML port of White-box-Cartoonization # https://github.com/SystemErrorWang/White-box-Cartoonization # https://www.runwayml.com # ========================================================================= import runway from runway.data_types import number, text, image, category, boolean from inpaint_model import PhotoInpaintModel effect_types = ['dolly-zoom-in', 'zoom-in', 'circle', 'swing'] setup_options = { 'model_path': text(description='Model path. Empty string = default model.'), } @runway.setup(options=setup_options) def setup(opts): model = PhotoInpaintModel() return model @runway.command( name='paint', inputs={ 'image': image(), 'resize':
labels = json.load(open('labels.json')) normalize = transforms.Normalize( mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225] ) preprocess = transforms.Compose([ transforms.Scale(256), transforms.CenterCrop(224), transforms.ToTensor(), normalize ]) @runway.setup def setup(): return models.squeezenet1_1(pretrained=True) @runway.command('classify', inputs={'photo': image() }, outputs={'label': text() }) def classify(model, inputs): img = inputs['photo'] img_tensor = preprocess(img) img_tensor.unsqueeze_(0) img_variable = Variable(img_tensor) fc_out = model(img_variable) label = labels[str(fc_out.data.numpy().argmax())] return {'label': label} if __name__ == '__main__': runway.run()
@runway.setup( options={ "checkpoint": runway.category(description="Pretrained checkpoints to use.", choices=['celebAHQ-512', 'celebAHQ-256', 'celeba'], default='celebAHQ-512') }) def setup(opts): model = BertForNextSentencePrediction.from_pretrained('bert-base-uncased') tokenizer = BertTokenizer.from_pretrained('bert-base-uncased') return model, tokenizer @runway.command(name='sequence_score', inputs={ 'line1': text(), 'next_line_candidates': text() }, outputs={'scores': array(item_type=number)}) def sequence_score(setup_tuple, inputs): model, tokenizer = setup_tuple line1 = inputs['line1'] outpath = line1[:5] + '.txt' outfile = open(outpath, 'w') next_line_candidates = inputs['next_line_candidates'] candidates = [line.strip() for line in next_line_candidates.split('\n')] loss_scores = [] for candidate in candidates: combined = inputs[ 'line1'] + ' ' + candidate # may be better to concatenate *after* tokenization using special [SEP] token input_tokens = tokenizer.encode(combined, add_special_tokens=True)
import json import runway from runway.data_types import image, text def nullModel(): return @runway.setup def setup(): return nullModel() @runway.command('classify', inputs={'image': text()}, outputs={'text': text()}) def classify(model, input): image = input.get("image") return {'text': image.upper()} if __name__ == '__main__': runway.run()
import runway from runway.data_types import text @runway.setup(options={"flavor": text(default="vanilla")}) def setup(opts): print("The selected flavor is {}".format(opts["flavor"])) runway.run() # curl -H "content-type: application/json" -d '{"flavor": "chocolate"}' http://localhost:8000/setup
# No options needed for this model. setup_options = {} # @runway.setup(options=setup_options) def setup(opts): model = TransformersModel(opts) return model # Query a text with a question @runway.command(name='query', inputs={ 'document': text(), 'question': text() }, outputs={ 'answer': text(), 'score': number(), 'start': number(), 'end': number() }, description='Ask a question about a text.') # def query(model, args): answer = model.query(args['document'], args['question']) return answer
@runway.setup(options=setup_options) def setup(opts): args = cli() # load model model, _ = nets.factory_from_args(args) model = model.to(args.device) processor = decoder.factory_from_args(args, model) return model, processor @runway.command(name='predict', inputs={'image': image()}, outputs={ 'keypoints': text(), 'image': image() }) def generate(m, inputs): args = cli() model, processor = m image = inputs["image"] # data preprocess = None if args.long_edge: preprocess = transforms.Compose([ transforms.Normalize(), transforms.RescaleAbsolute(args.long_edge), transforms.CenterPad(args.long_edge), ])