Giter Site home page Giter Site logo

manifest's Introduction

Manifest

How to make prompt programming with Foundation Models a little easier.

Table of Contents

Install

Install:

pip install manifest-ml

Install with diffusion support:

pip install manifest-ml[diffusers]

Install with HuggingFace local model support:

pip install manifest-ml[api]

Dev Install:

git clone [email protected]:HazyResearch/manifest.git
cd manifest
make dev

Getting Started

Running is simple to get started. If using OpenAI, set export OPENAI_API_KEY=<OPENAIKEY> (or pass key in through variable client_connection) then run

from manifest import Manifest

# Start a manifest session to OpenAI - default `engine=text-davinci-003`
manifest = Manifest(
    client_name = "openai",
)
manifest.run("Why is the grass green?")

Examples

We have example notebook and python scripts located at examples. These show how to use different models, model types (i.e. text, diffusers, or embedding models), and async running.

Manifest Components

Manifest is meant to be a very light weight package to help with prompt design and iteration. Three key design decisions of Manifest are

  • All models are behind APIs
  • Supports caching of model inputs/outputs for iteration, reproducibility, and cost saving
  • Unified API to support generate, score, and embed

Models

Manifest provides model clients for OpenAI, AI21, Cohere, Together, and HuggingFace (see below for how to use locally hosted HuggingFace models). You can toggle between the models by changing client_name and client_connection. For example, if a HuggingFace model is loaded locally, run

manifest = Manifest(
    client_name = "huggingface",
    client_connection = "http://127.0.0.1:5000",
)

If you want to use Cohere, run

manifest = Manifest(
    client_name = "cohere",
    client_connection = <COHERE_API_KEY>,
)

You can also just set export COHERE_API_KEY=<COHERE_API_KEY> and not use client_connection.

You can see the model details and possible model inputs to run() via

print(manifest.client_pool.get_current_client().get_model_params())
print(manifest.client_pool.get_current_client().get_model_inputs())

Global Cache

We support having queries and results stored in a global cache that can be shared across users. We treat inputs and outputs as key value pairs and support SQLite or Redis backends. To start with global caching using SQLite, run

manifest = Manifest(
    client_name = "openai",
    cache_name = "sqlite",
    cache_connection = "mycache.sqlite",
)

The cache will be saved in mycache.sqlite.

We also support Redis backend.

manifest = Manifest(
    client_name = "openai",
    cache_name = "redis",
    cache_connection = "localhost:6379"
)

As a hint, if you want to get Redis running, see the docker run command below under development.

Running Queries

Once you have a session open, you can write and develop prompts.

result = manifest.run("Hello, my name is Laurel")

You can also run over multiple examples if supported by the client.

results = manifest.run(["Where are the cats?", "Where are the dogs?"])

We support async queries as well via

import asyncio
results = asyncio.run(manifest.arun_batch(["Where are the cats?", "Where are the dogs?"]))

If something doesn't go right, you can also ask to get a raw manifest Response.

result_object = manifest.run(["Where are the cats?", "Where are the dogs?"], return_response=True)
print(result_object.get_request_obj())
print(result_object.is_cached())
print(result_object.get_response_obj())

By default, we do not truncate results based on a stop token. You can change this by either passing a new stop token to a Manifest session or to a run.

result = manifest.run(prompt, "Laurel", stop_token="and")

If you want to change default parameters to a model, we pass those as kwargs to the client.

result = manifest.run(prompt, "Laurel", max_tokens=50)

Streaming Queries

Manifest also supports streaming the model response back, assuming it's supported by the underlying client. When calling run, pass stream=True to get a streaming iterator in response.

result_iterator = manifest.run("Tell me a story. Once upon a time", max_tokens=100, stream=True)
for res_text in result_iterator:
    print(res_text)

Streaming responses are only supported for single string queries (not batch mode) for text completion models.

Model Pools

Manifest supports querying multiple models with different schedulers. This is very much a work in progress effort, but Manifest will round robin select (or randomly select) the clients you want. You can use the same client multiple times with different connection strings (e.g. different API keys), or you can mix and match. The only requirement is that all clients are the same request type. I.e. you can't have a pool of generation models and embedding models.

To query between a local model and OpenAI,

from manifest.connections.client_pool import ClientConnection
from manifest import Manifest

client_connection1 = ClientConnection(
    client_name="huggingface",
    client_connection="http://127.0.0.1:5000",
)
client_connection2 = ClientConnection(client_name="openai", engine="text-ada-001")
manifest = Manifest(
    client_pool=[client_connection1, client_connection2],
    cache_name="sqlite",
    client_connection=sqlite_cache,
)
manifest.run(...)

The speed benefit comes in with async batched runs. When calling arun_batch with a list of prompts, Manifest supports a chunk_size param. This will break the prompts into chunk_size chunks to spread across the client pool. By default chunk_size is -1 which means only one client will get all the prompts to run asynchronously. You must set chunk_size > 1 to distribute across the pool. There is a further batch_size param which control the individual client batch_size to send to the model.

responses = asyncio.run(manifest.arun_batch(prompts, max_tokens=30, chunk_size=20))

Other Models

Local Huggingface Models

To use a HuggingFace generative model, in manifest/api we have a Flask application that hosts the models for you.

In a separate terminal or Tmux/Screen session, to load 6B parameters models, run

python3 -m manifest.api.app \
    --model_type huggingface \
    --model_name_or_path EleutherAI/gpt-j-6B \
    --device 0

You will see the Flask session start and output a URL http://127.0.0.1:5000. Pass this in to Manifest. If you want to use a different port, set the FLASK_PORT environment variable.

manifest = Manifest(
    client_name = "huggingface",
    client_connection = "http://127.0.0.1:5000",
)

If you have a custom model you trained, pass the model path to --model_name_or_path.

To help load larger models, we also support using parallelize() from HF, accelerate, bitsandbytes, and deepspeed. You will need to install these packages first via pip install manifest-ml[api]. We list the commands to load larger models below.

  • T0pp
python3 -m manifest.api.app \
    --model_type huggingface \
    --model_name_or_path bigscience/T0pp \
    --use_hf_parallelize
  • NeoX 20B (requires at least 60GB of GPU memory)
python3 -m manifest.api.app \
    --model_type huggingface \
    --model_name_or_path EleutherAI/gpt-neox-20b \
    --use_accelerate_multigpu \
    --percent_max_gpu_mem_reduction 0.75
  • Bloom 175B (requires at least 240GB of GPU memory)
python3 -m manifest.api.app \
    --model_type huggingface \
    --model_name_or_path bigscience/bloom \
    --use_bitsandbytes \
    --percent_max_gpu_mem_reduction 0.85

Chat Models

Manifest has specific support for executing against chat models in the more standard "system" / "user" dialogue. To pass in a dialogue history to Manifest, use the run command with a list of dictionary inputs with role and content keys using an associated chat model such as openaichat.

manifest = Manifest(client_name="openaichat")
dialogue = [
    {"role": "system", "content": "You are a helpful assistant who also responds in rhymes"},
    {"role": "user", "content": "What is the date?"},
]
res = manifest.run(dialogue, max_tokens=100)

Embedding Models

Manifest also supports getting embeddings from models and available APIs. We do this all through changing the client_name argument. You still use run and abatch_run.

To use OpenAI's embedding models, simply run

manifest = Manifest(client_name="openaiembedding")
embedding_as_np = manifest.run("Get me an embedding for a bunny")

As explained above, you can load local HuggingFace models that give you embeddings, too. If you want to use a standard generative model, load the model as above use use client_name="huggingfaceembedding". If you want to use a standard embedding model, like those from SentenceTransformers, load your local model via

python3 -m manifest.api.app \
    --model_type sentence_transformers \
    --model_name_or_path all-mpnet-base-v2 \
    --device 0

Road Map

Here's what's coming up next

  • Clients
    • HuggingFace Hub
    • Azure OpenAI
    • Google Vertex
    • Anthropic
    • Streaming Support Completions
    • Streaming Support Chat Models
  • Data Types
    • Diffusion Models
  • Orchestration
    • Connection pools
  • Local Inference
    • FlexGen

Development

Before submitting a PR, run

export REDIS_PORT="6379"  # or whatever PORT local redis is running for those tests
cd <REDIS_PATH>
docker run -d -p 127.0.0.1:${REDIS_PORT}:6379 -v `pwd`:`pwd` -w `pwd` --name manifest_redis_test redis
make test

Cite

Please cite Manifest if you used it for any publications. Thanks!!

@misc{orr2022manifest,
  author = {Orr, Laurel},
  title = {Manifest},
  year = {2022},
  publisher = {GitHub},
  howpublished = {\url{https://github.com/HazyResearch/manifest}},
}

manifest's People

Contributors

anarayan avatar bnewm0609 avatar lorr1 avatar seyuboglu avatar srush avatar thakkarparth007 avatar yichern avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

manifest's Issues

Unable to initialize non-standard models from commandline

Description of the bug

I'm aware of --model_generation_type, but currently it allows to specify only "casual" model types. There's plenty of HF models not defined in MODEL_REGISTRY, which cannot be initialized without adding more generation types, or without reworking the mechanism to be more dynamic. For example, Manifest is not aware of BLOOMZ model, which uses BloomForCausalLM.

Expected behavior

Ability to define (at least) all models imported from transformers in huggingface.py.

Allow for re-running prompts without using run_batch

Description of the feature request

Hello, thank you for creating this library. As far as I can understand, due to caching it is not possible to run the same prompt/params multiple times and get a non-cached result

For the purpose of running prompts using parallel processing, or just generating results with the same input multiple times, it would be nice to be able to provide a flag which tells the client to re-run a prompt, and cache the result with a new key.

Perhaps have a re-run flag, which appends a unique string or param to the cache key, like a uuid or something? I'm happy to add this and PR it.

Add logprobs to request.

Add ability to get logprobs from clients.

  • Add to HF client
  • Pass in appropriate kwargs for run/batch_run

Unable to load HF T0pp in 8bit

Description of the bug

I have working example of T0pp running on my hardware, directly using transformer's AutoModelForSeq2SeqLM.from_pretrained() and I'm trying to load the model with manifest.

It seems impossible to pass parameters to "from_pretrained" method (in /api/models/huggingface.py). I need to pass load_in_8bit=True here and I believe this would fully solve my issue (as this is what I'm doing in my script).

To Reproduce

Steps to reproduce the behavior:

  1. There's no way how to pass load_in_8bit=True into from_pretrained() from python3 -m manifest.api.app --model_type huggingface --model_name_or_path bigscience/T0pp --device 0.

Expected behavior

Add possibility to pass arguments to huggingface's from_pretrained().

Accelerate memory too restrictive

Hook into accelerate to pass the max_mem keyword arg with around 85% of the current max memory. They have a helper function you can call to get the memory of each available gpu.

Streaming API

Super lo-pri but the OpenAI streaming API is really cool. Would be fun to add that somehow. (I'm moving minichain to just use Manifest for everything.)

import errors?

Description of the bug

Whenever I run the app and navigate to the url line 262 in manifest/manifest/api/app.py calls a metaseq resource. This isn't installed during setup.py which forces you to install metaseq from pypi which is a python2 library for genetic modeling.

To Reproduce

Steps to reproduce the behavior:
Build the manifest and run a module then go to the website at /

Expected behavior

App actually loads?

Error Logs/Screenshots

Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/pkg_resources/init.py", line 349, in get_provider
module = sys.modules[moduleOrReq]
KeyError: 'metaseq'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 2525, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 1822, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 1820, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python3.9/dist-packages/flask/app.py", line 1796, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "//manifest/manifest/api/app.py", line 262, in index
fn = pkg_resources.resource_filename("metaseq", "service/index.html")
File "/usr/local/lib/python3.9/dist-packages/pkg_resources/init.py", line 1135, in resource_filename
return get_provider(package_or_requirement).get_resource_filename(
File "/usr/local/lib/python3.9/dist-packages/pkg_resources/init.py", line 351, in get_provider
import(moduleOrReq)
ModuleNotFoundError: No module named 'metaseq'

Environment (please complete the following information)

  • WSL2 on FROM nvidia/cuda:11.3.1-cudnn8-devel-ubuntu20.04 image (docker)

Additional context

Add any other context about the problem here.

Adding ChatGPT API

Hi, could we have ChatGPT API in the manifest, since there have been a lot of ones to call it in GitHub these days, I think maybe many fans(of course including me) want to use that inside manifest for the unified interface to run more interesting demos and research experiments.
I can help with it if you would like to.๐Ÿ˜‰

HuggingFace Hub

It seems like HuggingFace is only supported for local models. It would be nice to support calling model on the Hub with the InferenceAPI. I think this is relatively straightforward to do, you just give the model name and the type of inference (text-generation or feature-extraction)

ChatGPT support

(while I'm adding requests)

ChatGPT API call requires different options Chat vs. Completions. Was going to add this to my lib, but am going to just move to manifest.

Packaging for PyPi

Description of the feature request

Related to #29, it would be very nice if this were a lightweight package that were available to pip install.

Description of the solution you'd like

Proposed solution:

  • The core library could be shipped with just requests and tqdm as dependencies. This would mean removing dependence on the cohere and openai packages, and replacing their clients' get_request methods with requests HTTP calls, similar to ai21_client

  • The caches could either be included, or shipped separately (as manifest-caches or something) to avoid dependence on sqllitedict and redis, as well as allowing for additional backends

  • The API package could be released separately for those who want to use it (as I feel the most common production usecase by far will be using HTTP), this removes dependence on flask, torch, transformers, etc


I am happy to work on this if you think this is a good/useful architecture. Perhaps it's worth a fork of the library at that point since I'm sure a good amount of research code now depends on this package as-is.

Output tokens in addition to token_logprobs

Description of the feature request

I'm working on a use case where I want to assign scores to different parts of the LLM output. The PR adding the token_logprobs (#59) goes a long way, but I think I need the corresponding tokens as well if I'm going to get the scores for a specific substring of the output.

Description of the solution you'd like

Probably just an additional field in the he output containing the tokenised output? Not the token ids, the word pieces.

Description of the alternatives you've considered

I can have the right tokenizer loaded locally to work out the token logprob alignment. Slightly defeats the promise of the Manifest approach though.

Additional context

Add any other context or screenshots about the feature request here.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.