Serverless AI inference via GitHub Actions — no server required
Project description
Servai
Serverless AI inference via GitHub Actions. No server. No GPU. No infrastructure.
Run open-source LLMs directly through GitHub's free CI/CD runners — just a GitHub token and a prompt. servai handles everything else: repo creation, workflow setup, model downloading, caching, and output retrieval.
Built by Tanish Chauhan
How it works
When you call ai_call():
- Creates a private GitHub repo (once, automatically)
- Commits a workflow + inference script into it
- Dispatches a
workflow_dispatchGitHub Actions run - The runner downloads and caches the model (GGUF quantized, ~0.6 GB)
- Runs inference via
llama-cpp-python - Uploads the output as an artifact
- Downloads and returns the output to you as a string
No server is ever running between calls. Each call spins up a fresh GitHub Actions runner, runs inference, and shuts down.
Install
pip install servai
Requirements:
- Python 3.9+
- A GitHub account with a personal access token (PAT)
- Token scopes needed:
repo,workflow
Getting a GitHub Token
You need a GitHub Personal Access Token (PAT) with repo and workflow scopes.
Classic token (recommended):
- Go to github.com/settings/tokens
- Click Generate new token > Generate new token (classic)
- Give it a name (e.g.
servai) - Set an expiration
- Check these scopes:
- `repo
from servai import ai_call
result = ai_call(
github_token="ghp_...",
prompt="explain recursion in simple terms",
)
print(result)
That's it. On first run, servai will:
- Create a repo called
servai-runneron your GitHub account - Set up the workflow automatically
- Download and cache TinyLlama 1.1B (~0.6 GB)
Subsequent calls reuse the cached repo and model.
Examples
Basic question
from servai import ai_call
result = ai_call(
github_token="ghp_...",
prompt="what is the difference between a list and a tuple in Python?",
)
print(result)
Custom system prompt
result = ai_call(
github_token="ghp_...",
prompt="explain black holes",
system="You are a physics professor. Be precise and use analogies.",
model="llama",
max_tokens=1024,
)
print(result)
Deterministic output (temperature=0)
result = ai_call(
github_token="ghp_...",
prompt="what is 144 divided by 12?",
temperature=0.0,
max_tokens=16,
)
print(result) # always returns the same answer
Silent mode (no logs)
result = ai_call(
github_token="ghp_...",
prompt="summarize the theory of evolution",
verbose=False,
)
print(result)
Large output
result = ai_call(
github_token="ghp_...",
prompt="write a detailed essay on the causes of World War I",
max_tokens=2048,
temperature=0.5,
model="llama",
)
print(result)
Multiple calls in sequence
from servai import ai_call
TOKEN = "ghp_..."
questions = [
"what is a neural network?",
"what is gradient descent?",
"what is backpropagation?",
]
for q in questions:
answer = ai_call(github_token=TOKEN, prompt=q, verbose=False)
print(f"Q: {q}\nA: {answer}\n")
Parallel calls (use separate repo per call)
import threading
from servai import ai_call
TOKEN = "ghp_..."
results = {}
def run(key, prompt, repo):
results[key] = ai_call(
github_token=TOKEN,
prompt=prompt,
repo_name=repo,
verbose=False,
)
t1 = threading.Thread(target=run, args=("q1", "explain DNA", "servai-repo-1"))
t2 = threading.Thread(target=run, args=("q2", "explain RNA", "servai-repo-2"))
t1.start(); t2.start()
t1.join(); t2.join()
print(results["q1"])
print(results["q2"])
Note: Parallel calls must use different
repo_namevalues. Each repo has its own independent run queue, so calls never interfere with each other.
Parameters
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
github_token |
str |
— | Yes | GitHub PAT with repo and workflow scopes |
prompt |
str |
— | Yes | The message or question to send to the model |
model |
str |
"tinyllama" |
No | Which model to use. See Models section below |
system |
str |
"You are a helpful assistant." |
No | System prompt that controls model behavior |
max_tokens |
int |
512 |
No | Max tokens to generate. Hard limit: 4096 |
temperature |
float |
0.7 |
No | Randomness. 0.0 = deterministic, 2.0 = very creative |
cache |
bool |
True |
No | Cache model weights between runs. Strongly recommended |
n_ctx |
int |
None |
No | Context window size. Defaults to model built-in. Max: 8192 |
repo_name |
str |
"servai-runner" |
No | GitHub repo to create or reuse for running inference |
verbose |
bool |
True |
No | Print step-by-step logs. Set False for silent mode |
Models
| Key | Model | Size | Default Context | Max Safe Context |
|---|---|---|---|---|
tinyllama |
TinyLlama 1.1B Chat Q4_K_M | 0.6 GB | 2048 tokens | 8192 tokens |
llama |
Llama 3.2 1B Instruct Q4_K_M | 0.7 GB | 4096 tokens | 8192 tokens |
Both models are quantized GGUF files hosted publicly on HuggingFace. No HuggingFace token required.
Which model should I use?
tinyllama— faster, smaller, good for short factual answers and simple tasksllama— better instruction-following, better for longer structured outputs and reasoning
Context and output size
The context window (n_ctx) is the total number of tokens the model can see at once — this includes your system prompt, your prompt, and the generated output combined.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gh_ai_runner-0.1.3.tar.gz.
File metadata
- Download URL: gh_ai_runner-0.1.3.tar.gz
- Upload date:
- Size: 10.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56a48a85c44ef2e1f1c548b62cdc02951d06fb45cd37976bd47bb3a8e7c70803
|
|
| MD5 |
1174e4c0db2fcfb2f1bc44964290a2e1
|
|
| BLAKE2b-256 |
8f8319ce6ae743a9be0f884c695b4d1b6ff93d72215b9a950c595b09d254198c
|
File details
Details for the file gh_ai_runner-0.1.3-py3-none-any.whl.
File metadata
- Download URL: gh_ai_runner-0.1.3-py3-none-any.whl
- Upload date:
- Size: 12.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b042d4f503de1e4d5e281900c844d1951faefc8560665f2b81acb29ac983896e
|
|
| MD5 |
04ce6ba93277d466f975bf9261ff1846
|
|
| BLAKE2b-256 |
6b40584a3f07ffa2fae02ce8367368d58a4254325f5a84b55daccad8028d6592
|