Skip to main content

Portable C++ avatar runtime — Python bindings via pybind11. Powers the bitHuman Essence pipeline cross-platform.

Project description

bithuman

This is the Python flavor of Layer 3: a platform-specific library for app developers. It wraps the Layer 1 libessence engine. For the CLI tool see docs/CLI.md.

┌─────────────────────────────────────────────────────────────┐
│ Layer 3: Platform-specific libraries (app developers)       │
│   - Python wheel       pip install bithuman    ◄──── you are here
│   - Swift package      SwiftPM Bithuman                     │
│   - Kotlin AAR         ai.bithuman:sdk                      │
│   - (future) Rust crate, JS/TS, Go, ...                     │
└─────────────────────────────────────────────────────────────┘
                          ▼ embeds
┌─────────────────────────────────────────────────────────────┐
│ Layer 2: bithuman CLI (end-user tool)                       │
│   - one cross-platform binary on macOS / Linux / Windows    │
│   - brew install bithuman · curl-pipe installer             │
└─────────────────────────────────────────────────────────────┘
                          ▼ links
┌─────────────────────────────────────────────────────────────┐
│ Layer 1: libessence engine (cross-platform C++ core)        │
│   - portable C ABI, same source on every target             │
│   - macOS · iOS · Android · Linux · Windows                 │
│   - never imported directly by app developers               │
└─────────────────────────────────────────────────────────────┘

Python bindings for the bitHuman SDK — the portable C++ avatar engine (libessence) that powers our cross-platform lipsync pipeline. The wheel ships a native pybind11 module that talks directly to libessence, so you get the same per-frame cost as our Swift and Kotlin clients with none of the GIL noise.

On an Apple M5 with 24 GB unified memory we measure ~640 FPS sustained compose (1.56 ms/frame mean, 2.03 ms p99) for a 1248×704 avatar, with ~206 MB peak RSS end-to-end. Cold load is ~14 ms for the fixture and ~400 ms for the first compose tick (lazy ONNX init).

This package is namespace-isolated from the v0 bithuman SDK; you can install both side-by-side.

Install

pip install bithuman

Status — Python wheel lags the rest of the SDK. The PyPI bithuman wheel is v1.12.4 (ABI v4), built from the legacy python/ tree at the root of bithuman-sdk. The new ABI-v6 streaming surface (be_runtime_push_audio / be_runtime_pull_frame / …) is C-level only in this binding tree until the Rust PyO3 wheel at cpp/bindings/rust/crates/bithuman-py ships to PyPI as the canonical replacement. Today's PyPI users keep the legacy AsyncBithuman.push_audio + async for ... in runtime.run() shape — see the legacy quickstart.

Compatibility

  • Platforms: macOS arm64, Linux x86_64, Linux arm64 — all ship as wheels. Windows is tracked for a follow-up.
  • Python: 3.10 – 3.13 (cp310, cp311, cp312, cp313). CPython only.
  • ABI: the published wheel wraps libessence ABI v4. The libessence engine itself is on ABI v6 — that surface is currently exposed via the Swift / Kotlin / Rust bindings only. PyO3 wheel migration in flight.
  • Auth: ships with live heartbeat against api.bithuman.ai baked into libessence. Avatar.load(api_secret=...) is the entry point; BITHUMAN_API_SECRET env var works too. Set BITHUMAN_UNMETERED=1 for dev / parity-test runs.

What you get

The package exposes three API tiers (all importable from bithuman):

Tier Types Use when…
Async AsyncAvatar, AudioChunk, VideoControl, VideoFrame Hosting a service / parity with legacy AsyncBithuman
Sync facade Avatar, ComposedFrame, EP Offline / batch / CLI rendering
Low-level Fixture, Runtime, EP_CPU/EP_AUTO/EP_COREML/EP_NNAPI/EP_QNN Direct C ABI access, custom audio pipeline

Error types: BithumanError (base), TokenError / TokenExpiredError / TokenValidationError / TokenRequestError / AccountStatusError (auth), ModelError / ModelNotFoundError / ModelLoadError / ModelSecurityError / ExpressionModelNotSupported (fixture), RuntimeNotReadyError.

Version info: bithuman.__version__ (Python package), bithuman.__core_version__ (linked libessence), bithuman.__abi_version__.

Quickstart (legacy AsyncBithuman — PyPI)

This is the shape of the current published wheel. It ports directly from the v0 bithuman SDK: feed PCM with push_audio, drain frames from the runtime.run() async generator.

import asyncio
from bithuman import AsyncBithuman

async def main():
    runtime = await AsyncBithuman(
        model_path="model.imx",
        api_secret="...",  # or BITHUMAN_API_SECRET env var
    ).start()

    await runtime.push_audio(pcm_16k_mono_int16_bytes,
                             sample_rate=16000, last_chunk=True)

    async for frame in runtime.run():
        # frame.bgr_image is (H, W, 3) uint8 in BGR order
        ...

asyncio.run(main())

PCM accepted is int16 little-endian bytes at 16 kHz mono. WAV / MP3 / FLAC / OGG decoding is the caller's responsibility (use soundfile).

Quickstart (low-level, C-level streaming surface)

The Rust PyO3 wheel will expose the ABI-v6 streaming pair (runtime.push_audio + runtime.pull_frame) on the same shape as the Swift / Kotlin bindings. Until it ships to PyPI, the snippet below uses the legacy Fixture / Runtime types in the published wheel.

CLI

A essence-render console script ships with the wheel:

pip install 'bithuman[cli]'

essence-render \
  --model ~/.cache/bithuman/models/sample-avatar.imx \
  --audio speech.wav \
  --output out.mp4

Pass --output - to stream raw BGR24 frames to stdout (handy for piping into a separate ffmpeg pipeline or a custom encoder). Other flags:

Flag Default Description
--fps 25 Output FPS for the MP4 container.
--quality 80 libx264 quality 1..100 (higher = better).
--ep cpu Execution provider hint (cpu/auto/coreml/…).
--threads 1 ORT intra-op thread count.
--no-audio Skip audio muxing; produce a silent video.

Example end-to-end run (5 s sine sweep):

essence-render 0.1.0: model=sample-avatar.imx audio=sine_sweep_5s.wav ep=cpu threads=1
essence-render: loaded fixture in 14.9 ms — 1248x704 @ 25 fps, 183 clusters, 202 src frames
essence-render: composed 122 frames in 1.83s (14.96 ms/frame, 66.8 fps)
essence-render: wrote /tmp/sine_sweep_5s.mp4

(Throughput here is bounded by H.264 encode, not Essence inference. Use --output - if you want to measure raw compose speed.)

Low-level API

If you need finer control or want to swap in a custom audio pipeline, the C ABI is exposed directly:

import numpy as np
from bithuman import Fixture, Runtime, EP_CPU

fx = Fixture("model.imx", preferred_ep=EP_CPU, intra_op_threads=1)
rt = Runtime(fx)
pcm = np.fromfile("speech.f32", dtype=np.float32)  # 16 kHz mono float32
cluster_idx, bgr = rt.tick_compose(pcm, frame_idx_hint=-1)
# bgr.shape == (fx.frame_height, fx.frame_width, 3), dtype uint8

Pass the entire pcm buffer to each tick_compose call; the runtime maintains an internal cursor and advances one tick per call until the audio is exhausted.

Zero-alloc hot path (since 1.12.4)

For tight render loops, pre-allocate the BGR buffer once and pass it via out=. The runtime writes into it in place and returns just the cluster_idx. This drops wrapper overhead to within ~3 % of raw libessence (vs ~8 % for the alloc-per-tick path):

out = np.empty((fx.frame_height, fx.frame_width, 3), dtype=np.uint8)
for _ in range(num_ticks):
    cluster_idx = rt.tick_compose(pcm, -1, out=out)
    # `out` now holds this tick's frame; read it before the next call.

The same out= keyword works on tick_compose_to_size. See docs/ARCHITECTURE.md §9 for the cross-wrapper perf table.

Build from source

You need the prebuilt parent C++ archive at cpp/build/libessence.a (run the parent CMake build first), plus the runtime deps from Homebrew (onnxruntime, webp, ffmpeg, hdf5, jpeg-turbo).

cd cpp/bindings/python
uv pip install -e '.[cli,test]' --no-build-isolation

The CMake glue links the prebuilt static archive directly — it does NOT re-run the parent build, so iterate on bindings without paying the C++ rebuild cost.

Performance

Measured with tests/bench.py against the v1 compose path (audio → composited BGR frame) on Apple M5 24 GB, libessence 1.16.0:

Metric Alloc per tick out= reuse buffer
Steady-state mean 1.53 ms / frame 1.45 ms / frame
p99 1.66 ms 1.53 ms
Sustained throughput 655 FPS 692 FPS
Overhead vs raw libessence +8.3 % +2.6 %
Peak RSS (proc) 192 MB 182 MB

Wrapper overhead is within 5 % of raw libessence on the out= path; see docs/ARCHITECTURE.md §9 for the apples-to-apples methodology and the cross-wrapper comparison. Reproduce with:

scripts/bench-wrappers.sh

Linux wheels

Pre-built manylinux_2_28 wheels ship for x86_64 + aarch64 across cp310 through cp313 — 8 wheels in total, all auditwheel-repaired with the full dep tree bundled (ORT, FFmpeg, HDF5, libjpeg-turbo, libwebp, libcurl, OpenSSL).

To rebuild them locally:

# One-time: build the dep-baked Docker images (~10 min each).
docker build --platform linux/amd64 -t libessence/manylinux-x86_64:0.1 \
    -f scripts/Dockerfile.manylinux-x86_64 scripts/
docker build --platform linux/arm64/v8 -t libessence/manylinux-aarch64:0.1 \
    -f scripts/Dockerfile.manylinux-aarch64 scripts/

# Per wheel build (~2 min):
docker run --rm --platform linux/amd64 -v "$REPO":/src \
    -e PYTAG=cp311 -e ARCH_INSIDE=x86_64 \
    libessence/manylinux-x86_64:0.1 \
    bash /src/cpp/bindings/python/scripts/build-wheel-in-container.sh

Limitations

  • Windows wheels not yet built — tracked for v0.2.
  • The CLI's output framerate is fixed at 25 fps to match the model's internal rate. Pass --output - and pipe to your own encoder if you need temporal resampling.
  • preferred_ep=COREML/NNAPI/QNN is accepted but currently no-ops to CPU in the v0.1 build.

License

Commercial. Contact hello@bithuman.ai.

See also

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

bithuman-1.19.1-cp314-cp314-manylinux_2_28_x86_64.whl (18.2 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ x86-64

bithuman-1.19.1-cp314-cp314-manylinux_2_28_aarch64.whl (17.1 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ ARM64

bithuman-1.19.1-cp314-cp314-macosx_26_0_arm64.whl (26.9 MB view details)

Uploaded CPython 3.14macOS 26.0+ ARM64

bithuman-1.19.1-cp313-cp313-manylinux_2_28_x86_64.whl (18.2 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

bithuman-1.19.1-cp313-cp313-manylinux_2_28_aarch64.whl (17.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

bithuman-1.19.1-cp313-cp313-macosx_26_0_arm64.whl (26.9 MB view details)

Uploaded CPython 3.13macOS 26.0+ ARM64

bithuman-1.19.1-cp312-cp312-manylinux_2_28_x86_64.whl (18.2 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

bithuman-1.19.1-cp312-cp312-manylinux_2_28_aarch64.whl (17.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

bithuman-1.19.1-cp312-cp312-macosx_26_0_arm64.whl (26.9 MB view details)

Uploaded CPython 3.12macOS 26.0+ ARM64

bithuman-1.19.1-cp311-cp311-manylinux_2_28_x86_64.whl (18.2 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

bithuman-1.19.1-cp311-cp311-manylinux_2_28_aarch64.whl (17.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

bithuman-1.19.1-cp311-cp311-macosx_26_0_arm64.whl (26.9 MB view details)

Uploaded CPython 3.11macOS 26.0+ ARM64

bithuman-1.19.1-cp310-cp310-manylinux_2_28_x86_64.whl (18.2 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

bithuman-1.19.1-cp310-cp310-manylinux_2_28_aarch64.whl (17.0 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

bithuman-1.19.1-cp310-cp310-macosx_26_0_arm64.whl (26.8 MB view details)

Uploaded CPython 3.10macOS 26.0+ ARM64

bithuman-1.19.1-cp39-cp39-manylinux_2_28_x86_64.whl (18.2 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ x86-64

bithuman-1.19.1-cp39-cp39-manylinux_2_28_aarch64.whl (17.1 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ ARM64

bithuman-1.19.1-cp39-cp39-macosx_26_0_arm64.whl (26.9 MB view details)

Uploaded CPython 3.9macOS 26.0+ ARM64

File details

Details for the file bithuman-1.19.1-cp314-cp314-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 cf41cb1e090df0e39f4367915034adb745904839b5faff4dcf62aad3aee46d95
MD5 68affefeb516b4979c098987ddf1c84e
BLAKE2b-256 2d1b69a19163b68d59a0b87fd264845cc07e395e3346fcab36dce10d0cc97dcb

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp314-cp314-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp314-cp314-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ab0ae96f13c8ed233843de53f944c2a0130ae6b6aac4c0afdd6b529438d7354c
MD5 ad55531e09335019312de603c77c4b87
BLAKE2b-256 aaf10edb7f283e482b28609392e27e9d3cbe0cb820441f0ed16e5be249637172

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp314-cp314-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp314-cp314-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 30c5df0f492b86d2db57e0c9ec22dbf214243be8a8e4c0e8f59f226d03f0f3f9
MD5 03e5981b5b4223636c0fb77c4dbcada6
BLAKE2b-256 ba32b704dd290b5bca2f99af42b39a0823e4fe09d6caa48fbaa639497b0acb51

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 bcc8d37076ac36bb7823e882c64b63439bc49d7cd414b83b81f881b50f973c4c
MD5 3d056da9d455420e3297df8ccda293c5
BLAKE2b-256 81d345aa4c982a34218a27f68c524f493fba4a031b32ad8d7da2eb69dc9569d6

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp313-cp313-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 facc6b60801a8bda0372b3c08e8bf383c8a6a32e43a4990500b9acc25aae8d1b
MD5 e51f76f2462bf2c7be008734e18966c7
BLAKE2b-256 374b990414e15b0681b0c621b5e5f56856c982c0093fbdef01c4491298983d47

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp313-cp313-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp313-cp313-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 c599ba9758dcdcde4b84fc0be7448fe74122299b9c83aadd6cb094b5bed43483
MD5 4fc835e3265401699eee1a5c07cdd136
BLAKE2b-256 23817a78160d1d3c5a56a0ea174c10a540ccbae876dc3e1c1e78d2a43c4610fe

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b297d23e5fb4b813a82caf983fed8b2c93c80370f24a600d484936bb309df2b1
MD5 47e8b0eccfec8e9253d880e4a5ffc3b1
BLAKE2b-256 110247d588e4f89502c884a67b75b1cd28159e64c05adef751b7b37fc896de92

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp312-cp312-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0329aaf5aafbf79e31832d690644645deba166a73f882cbf38bbc6f389a2afc3
MD5 19ab1873ff1dd340cdcd62e30f4ac6bc
BLAKE2b-256 47cb2398888053286c90b66d64e149371360ae3d75f9f818baf82ae7e122745f

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp312-cp312-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp312-cp312-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 752fe4ad85638432fbf4dbae0952aaacd14477adb4863f4431a3be426a7938ac
MD5 1de7ae980491ebffcb4a4a49aed27ba4
BLAKE2b-256 fe19f2c4c66c30d7f5bf1ab1e1265d0946945ecbd6bdea5ca2ffe6cb3a356f5b

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 00746a54a3b8e7ea93d796b9508cbd21d9dba9ddc72ee9739ee2150e3dc64656
MD5 05e901a7c69e414c744d9c3b340f2e9a
BLAKE2b-256 0bb867f5f3a624d074cd29b7fa48c9316dc345bd70cc14ca4b3000214f6ca8af

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp311-cp311-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 78ac37d8b7a2afeb3f9491c132eeefaadd30d7dd557299cc9f9343afd3424c9e
MD5 b30d4636c863d530f1120b2cd627b07a
BLAKE2b-256 2937b5ed57656fef22c129b639679f69d33851f49a6d9a082bb9d52bc5c58b24

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp311-cp311-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp311-cp311-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 5e3e2e11c82297cd92e524afb3dadecf903e1e3f0bde93f93ec54b83d4b8cb7b
MD5 b904e54b18861c74fc6380c60e9461dc
BLAKE2b-256 1653607b12c9d8bbb07148c5a2b2ac29149c195103fa575b5aaa5d48d6f141f2

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 287b36b2454cca42182066fb2bdf770199efa43a66120a522c693573c23d6953
MD5 4664049e7def38bc6e809f9d3761e2fa
BLAKE2b-256 12609236bc49c514f8be897c7f7532c151470aef9f86e6feb72985a5c8888571

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp310-cp310-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3d0300fd025b47d83d6e1431838113860eb36bf29f995d173d7a805cc298b47f
MD5 d05c76f1a634f0d31e101916cc34a917
BLAKE2b-256 3002ccbae32e135ebb64f57527a4ca7a4afb71c9001e6a4e690d35c987ed2393

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp310-cp310-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp310-cp310-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 20fafcd63c35da343a3e535f69dd747c4f5c09d37466aa4687e703a14ef91e0a
MD5 24911a133cf971c3365bca76e2bd2365
BLAKE2b-256 0d8a52b65f834ee1f7ff62034f1647fa0e94578dd33d675bb857a90421914209

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp39-cp39-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a1c5d9002635016b5be190c9c669f1d670ef16c8b1e2a8b321937bf0ea552120
MD5 e4203615327639aa8d9499d281bd2747
BLAKE2b-256 ded9142c913d6cb7d93b58b196cab31d6759eb7b7e3fb3e39a57dded465b6a48

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp39-cp39-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp39-cp39-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7bf61a9ebdfefd48a0362315377f2c6060998ba94356269cb370d16b4b00dec6
MD5 15eb8507a2443aa6f5aed8b172b516dd
BLAKE2b-256 98706fc00e3ea180bc3d60dbe6797a9b3bf1ac96b9f4d13ffe80f4629cace0fc

See more details on using hashes here.

File details

Details for the file bithuman-1.19.1-cp39-cp39-macosx_26_0_arm64.whl.

File metadata

File hashes

Hashes for bithuman-1.19.1-cp39-cp39-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 f2d4d3322ac326603ac18bc28e504c326a68e664ac097e888383afd58899a762
MD5 15e2e952a6853d476e40be5ac9a4eddd
BLAKE2b-256 cd8889c8859b68927f6e5b69ba8c65a824e138e26680560b64282a238ed9a23d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page