ucall

Web Serving and Remote Procedure Calls at 50x lower latency and 70x higher bandwidth than FastAPI, implementing JSON-RPC & REST over io_uring ☎️

https://github.com/unum-cloud/ucall

Science Score: 54.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
  • Academic publication links
  • Committers with academic emails
    1 of 13 committers (7.7%) from academic institutions
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (7.6%) to scientific vocabulary

Keywords

backend cpython dpdk epoll fast-api flask http http-server io-uring json json-rpc liburing linux-kernel python rest-api rpc rpc-framework simd tcp tcp-ip

Keywords from Contributors

semantic-search image-search vector-search webassembly text-search similarity-search search-engine recommender-system nearest-neighbor-search kann
Last synced: 4 months ago · JSON representation ·

Repository

Web Serving and Remote Procedure Calls at 50x lower latency and 70x higher bandwidth than FastAPI, implementing JSON-RPC & REST over io_uring ☎️

Basic Info
Statistics
  • Stars: 1,248
  • Watchers: 21
  • Forks: 51
  • Open Issues: 14
  • Releases: 20
Topics
backend cpython dpdk epoll fast-api flask http http-server io-uring json json-rpc liburing linux-kernel python rest-api rpc rpc-framework simd tcp tcp-ip
Created almost 3 years ago · Last pushed 12 months ago
Metadata Files
Readme License Citation

README.md

UCall

JSON Remote Procedure Calls Library
Up to 100x Faster than FastAPI


Discord     LinkedIn     Twitter     Blog     GitHub


Most modern networking is built either on slow and ambiguous REST APIs or unnecessarily complex gRPC. FastAPI, for example, looks very approachable. We aim to be equally or even simpler to use.

FastAPIUCall
```sh pip install fastapi uvicorn ``` ```sh pip install ucall ```
```python from fastapi import FastAPI import uvicorn server = FastAPI() @server.get('/sum') def sum(a: int, b: int): return a + b uvicorn.run(...) ``` ```python from ucall.posix import Server # from ucall.uring import Server on 5.19+ server = Server() @server def sum(a: int, b: int): return a + b server.run() ```

It takes over a millisecond to handle a trivial FastAPI call on a recent 8-core CPU. In that time, light could have traveled 300 km through optics to the neighboring city or country, in my case. How does UCall compare to FastAPI and gRPC?

| Setup | 🔁 | Server | Latency w 1 client | Throughput w 32 clients | | :---------------------- | :---: | :----: | -----------------: | ----------------------: | | Fast API over REST | ❌ | 🐍 | 1'203 μs | 3'184 rps | | Fast API over WebSocket | ✅ | 🐍 | 86 μs | 11'356 rps ¹ | | gRPC ² | ✅ | 🐍 | 164 μs | 9'849 rps | | | | | | | | UCall with POSIX | ❌ | C | 62 μs | 79'000 rps | | UCall with iouring | ✅ | 🐍 | 40 μs | 210'000 rps | | UCall with iouring | ✅ | C | 22 μs | 231'000 rps |

Table legend All benchmarks were conducted on AWS on general purpose instances with **Ubuntu 22.10 AMI**. It is the first major AMI to come with **Linux Kernel 5.19**, featuring much wider `io_uring` support for networking operations. These specific numbers were obtained on `c7g.metal` beefy instances with Graviton 3 chips. - The 🔁 column marks, if the TCP/IP connection is being reused during subsequent requests. - The "server" column defines the programming language, in which the server was implemented. - The "latency" column report the amount of time between sending a request and receiving a response. μ stands for micro, μs subsequently means microseconds. - The "throughput" column reports the number of Requests Per Second when querying the same server application from multiple client processes running on the same machine. > ¹ FastAPI couldn't process concurrent requests with WebSockets. > ² We tried generating C++ backends with gRPC, but its numbers, suspiciously, weren't better. There is also an async gRPC option, that wasn't tried.

How is that possible?!

How can a tiny pet-project with just a couple thousand lines of code compete with two of the most established networking libraries? UCall stands on the shoulders of Giants:

  • io_uring for interrupt-less IO.

    • io_uring_prep_read_fixed on 5.1+.
    • io_uring_prep_accept_direct on 5.19+.
    • io_uring_register_files_sparse on 5.19+.
    • IORING_SETUP_COOP_TASKRUN optional on 5.19+.
    • IORING_SETUP_SINGLE_ISSUER optional on 6.0+.
  • SIMD-accelerated parsers with manual memory control.

You have already seen the latency of the round trip..., the throughput in requests per second..., want to see the bandwidth? Try yourself!

python @server def echo(data: bytes): return data

More Functionality than FastAPI

FastAPI supports native type, while UCall supports numpy.ndarray, PIL.Image and other custom types. This comes handy when you build real applications or want to deploy Multi-Modal AI, like we do with UForm.

```python from ucall.rich_posix import Server import uform

server = Server() model = uform.get_model('unum-cloud/uform-vl-multilingual')

@server def vectorize(description: str, photo: PIL.Image.Image) -> numpy.ndarray: image = model.preprocessimage(photo) tokens = model.preprocesstext(description) jointembedding = model.encodemultimodal(image=image, text=tokens)

return joint_embedding.cpu().detach().numpy()

```

We also have our own optional Client class that helps with those custom types.

```python from ucall.client import Client

client = Client()

Explicit JSON-RPC call:

response = client({ 'method': 'vectorize', 'params': { 'description': description, 'image': image, }, 'jsonrpc': '2.0', 'id': 100, })

Or the same with syntactic sugar:

response = client.vectorize(description=description, image=image) ```

CLI like cURL

Aside from the Python Client, we provide an easy-to-use Command Line Interface, which comes with pip install ucall. It allow you to call a remote server, upload files, with direct support for images and NumPy arrays. Translating previous example into a Bash script, to call the server on the same machine:

sh ucall vectorize description='Product description' -i image=./local/path.png

To address a remote server:

sh ucall vectorize description='Product description' -i image=./local/path.png --uri 0.0.0.0 -p 8545

To print the docs, use ucall -h:

```txt usage: ucall [-h] [--uri URI] [--port PORT] [-f [FILE ...]] [-i [IMAGE ...]] [--positional [POSITIONAL ...]] method [kwargs ...]

UCall Client CLI

positional arguments: method method name kwargs method arguments

options: -h, --help show this help message and exit --uri URI server uri --port PORT server port -f [FILE ...], --file [FILE ...] method positional arguments -i [IMAGE ...], --image [IMAGE ...] method positional arguments --positional [POSITIONAL ...] method positional arguments ```

You can also explicitly annotate types, to distinguish integers, floats, and strings, to avoid ambiguity.

ucall auth id=256 ucall auth id:int=256 ucall auth id:str=256

Free Tier Throughput

We will leave bandwidth measurements to enthusiasts, but will share some more numbers. The general logic is that you can't squeeze high performance from Free-Tier machines. Currently AWS provides following options: t2.micro and t4g.small, on older Intel and newer Graviton 2 chips. This library is so fast, that it doesn't need more than 1 core, so you can run a fast server even on a tiny Free-Tier server!

| Setup | 🔁 | Server | Clients | t2.micro | t4g.small | | :---------------------- | :---: | :----: | :-----: | ---------: | ----------: | | Fast API over REST | ❌ | 🐍 | 1 | 328 rps | 424 rps | | Fast API over WebSocket | ✅ | 🐍 | 1 | 1'504 rps | 3'051 rps | | gRPC | ✅ | 🐍 | 1 | 1'169 rps | 1'974 rps | | | | | | | | | UCall with POSIX | ❌ | C | 1 | 1'082 rps | 2'438 rps | | UCall with iouring | ✅ | C | 1 | - | 5'864 rps | | UCall with POSIX | ❌ | C | 32 | 3'399 rps | 39'877 rps | | UCall with iouring | ✅ | C | 32 | - | 88'455 rps |

In this case, every server was bombarded by requests from 1 or a fleet of 32 other instances in the same availability zone. If you want to reproduce those benchmarks, check out the sum examples on GitHub.

Quick Start

For Python:

sh pip install ucall

For CMake projects:

cmake include(FetchContent) FetchContent_Declare( ucall GIT_REPOSITORY https://github.com/unum-cloud/ucall GIT_SHALLOW TRUE ) FetchContent_MakeAvailable(ucall) include_directories(${ucall_SOURCE_DIR}/include)

The C usage example is mouthful compared to Python. We wanted to make it as lightweight as possible and to allow optional arguments without dynamic allocations and named lookups. So unlike the Python layer, we expect the user to manually extract the arguments from the call context with ucall_param_named_i64(), and its siblings.

```c

include

include

static void sum(ucallcallt call, ucallcallbacktagt) { int64t a{}, b{}; char printedsum[256]{}; bool gota = ucallparamnamedi64(call, "a", 0, &a); bool gotb = ucallparamnamedi64(call, "b", 0, &b); if (!gota || !gotb) return ucallcallreplyerrorinvalidparams(call);

int len = snprintf(printed_sum, 256, "%ll", a + b);
ucall_call_reply_content(call, printed_sum, len);

}

int main(int argc, char** argv) {

ucall_server_t server{};
ucall_config_t config{};

ucall_init(&config, &server);
ucall_add_procedure(server, "sum", &sum, NULL);
ucall_take_calls(server, 0);
ucall_free(server);
return 0;

} ```

Roadmap

  • [x] Batch Requests
  • [x] JSON-RPC over raw TCP sockets
  • [x] JSON-RPC over TCP with HTTP
  • [x] Concurrent sessions
  • [x] NumPy array and Pillow serialization
  • [ ] HTTPS support
  • [ ] Batch-capable endpoints for ML
  • [ ] Zero-ETL relay calls
  • [ ] Integrating with UKV
  • [ ] WebSockets for web interfaces
  • [ ] AF_XDP and UDP-based analogs on Linux

Want to affect the roadmap and request a feature? Join the discussions on Discord.

Why JSON-RPC?

  • Transport independent: UDP, TCP, bring what you want.
  • Application layer is optional: use HTTP or not.
  • Unlike REST APIs, there is just one way to pass arguments.

Owner

  • Name: Unum
  • Login: unum-cloud
  • Kind: organization
  • Email: info@unum.cloud
  • Location: Armenia

Scaling Intelligence

Citation (CITATION.cff)

cff-version: 1.2.0
message: "If you use this software, please cite it as below."
authors:
- family-names: "Vardanian"
  given-names: "Ash"
  orcid: "https://orcid.org/0000-0002-4882-1815"
title: "UCall by Unum Cloud"
version: 0.5.0
doi: 10.5281/zenodo.7951497
date-released: 2023-01-03
url: "https://github.com/unum-cloud/ucall"

GitHub Events

Total
  • Watch event: 106
  • Issue comment event: 6
  • Push event: 2
  • Pull request event: 2
  • Fork event: 9
  • Create event: 1
Last Year
  • Watch event: 106
  • Issue comment event: 6
  • Push event: 2
  • Pull request event: 2
  • Fork event: 9
  • Create event: 1

Committers

Last synced: 7 months ago

All Time
  • Total Commits: 434
  • Total Committers: 13
  • Avg Commits per committer: 33.385
  • Development Distribution Score (DDS): 0.53
Past Year
  • Commits: 4
  • Committers: 3
  • Avg Commits per committer: 1.333
  • Development Distribution Score (DDS): 0.5
Top Committers
Name Email Commits
Ishkhan Nazaryan 1****2 204
Ashot Vardanian 1****n 185
semantic-release-bot s****t@m****t 17
DarvinHarutyunyan 1****n 12
Narek Galstyan n****g@b****u 4
Gurgen Yegoryan g****n@g****m 2
Arman Ghazaryan 9****n 2
davitunum d****t@u****m 2
TinySemVer t****r@a****m 2
vov_or 3****R 1
Richard Sufliarsky 3****y 1
Mark Reed 5****Z 1
1lumin 5****n 1
Committer Domains (Top 20 + Academic)

Issues and Pull Requests

Last synced: 4 months ago

All Time
  • Total issues: 30
  • Total pull requests: 84
  • Average time to close issues: about 1 month
  • Average time to close pull requests: 2 days
  • Total issue authors: 14
  • Total pull request authors: 13
  • Average comments per issue: 1.97
  • Average comments per pull request: 0.8
  • Merged pull requests: 75
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 2
  • Pull requests: 6
  • Average time to close issues: about 8 hours
  • Average time to close pull requests: about 3 hours
  • Issue authors: 2
  • Pull request authors: 4
  • Average comments per issue: 1.5
  • Average comments per pull request: 0.83
  • Merged pull requests: 3
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • ashvardanian (12)
  • ishkhan42 (5)
  • MarkReedZ (2)
  • rockerBOO (1)
  • Bing-su (1)
  • mtasic85 (1)
  • sctrueew (1)
  • biplobmanna (1)
  • rswgnu (1)
  • sdebionne (1)
  • laclouis5 (1)
  • ArashPartow (1)
  • mmk32001 (1)
Pull Request Authors
  • ashvardanian (32)
  • ishkhan42 (27)
  • MarkReedZ (12)
  • vitaut (6)
  • nilq (2)
  • RichardSufliarsky (2)
  • ab-10 (2)
  • sdebionne (2)
  • gurgenyegoryan (2)
  • crazy-max (1)
  • herpiko (1)
  • VoVoR (1)
  • 1lumin (1)
Top Labels
Issue Labels
enhancement (16) bug (10) invalid (10) released (3) good first issue (2)
Pull Request Labels
released (38)

Packages

  • Total packages: 2
  • Total downloads:
    • pypi 709 last-month
  • Total dependent packages: 1
    (may contain duplicates)
  • Total dependent repositories: 1
    (may contain duplicates)
  • Total versions: 29
  • Total maintainers: 1
pypi.org: ucall

Up to 100x Faster FastAPI. JSON-RPC with io_uring, SIMD-acceleration, and pure CPython bindings

  • Versions: 6
  • Dependent Packages: 1
  • Dependent Repositories: 1
  • Downloads: 709 Last month
Rankings
Stargazers count: 2.1%
Downloads: 2.6%
Dependent packages count: 7.4%
Forks count: 8.1%
Average: 8.5%
Dependent repos count: 22.3%
Maintainers (1)
Last synced: 4 months ago
proxy.golang.org: github.com/unum-cloud/ucall
  • Versions: 23
  • Dependent Packages: 0
  • Dependent Repositories: 0
Rankings
Dependent packages count: 9.0%
Average: 9.6%
Dependent repos count: 10.2%
Last synced: 4 months ago

Dependencies

setup.py pypi
  • numpy >=1.16
  • pillow *
.github/workflows/release.yml actions
  • actions/checkout v3 composite
  • actions/configure-pages v2 composite
  • actions/deploy-pages v1 composite
  • actions/download-artifact v3.0.2 composite
  • actions/setup-node v3 composite
  • actions/setup-python v3 composite
  • actions/upload-artifact v3 composite
  • actions/upload-pages-artifact v1 composite
  • crazy-max/ghaction-setup-docker v1.0.0 composite
  • docker/setup-qemu-action v2.1.0 composite
  • pypa/gh-action-pypi-publish v1.6.4 composite
.devcontainer/Dockerfile docker
  • ubuntu 22.04 build
.github/workflows/package.json npm
  • @semantic-release/exec github:semantic-release/exec development
  • @semantic-release/git ^10.0.1 development
  • conventional-changelog-eslint ^3.0.9 development
  • semantic-release ^20.1.3 development
.github/workflows/prerelease.yml actions
  • actions/checkout v3 composite
  • actions/setup-python v4 composite
pyproject.toml pypi