Skip to main content

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

Reason this release was yanked:

the C++ runtime has a deeper incompatibility that prevents it from loading any production .imx file.

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.18.0-cp313-cp313-manylinux_2_28_x86_64.whl (14.5 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

bithuman-1.18.0-cp313-cp313-manylinux_2_28_aarch64.whl (13.4 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

bithuman-1.18.0-cp313-cp313-macosx_26_0_arm64.whl (23.3 MB view details)

Uploaded CPython 3.13macOS 26.0+ ARM64

bithuman-1.18.0-cp312-cp312-manylinux_2_28_x86_64.whl (14.5 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

bithuman-1.18.0-cp312-cp312-manylinux_2_28_aarch64.whl (13.4 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

bithuman-1.18.0-cp312-cp312-macosx_26_0_arm64.whl (23.3 MB view details)

Uploaded CPython 3.12macOS 26.0+ ARM64

bithuman-1.18.0-cp311-cp311-manylinux_2_28_x86_64.whl (14.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

bithuman-1.18.0-cp311-cp311-manylinux_2_28_aarch64.whl (13.4 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

bithuman-1.18.0-cp311-cp311-macosx_26_0_arm64.whl (23.3 MB view details)

Uploaded CPython 3.11macOS 26.0+ ARM64

bithuman-1.18.0-cp310-cp310-manylinux_2_28_x86_64.whl (14.5 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

bithuman-1.18.0-cp310-cp310-manylinux_2_28_aarch64.whl (13.4 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

bithuman-1.18.0-cp310-cp310-macosx_26_0_arm64.whl (23.3 MB view details)

Uploaded CPython 3.10macOS 26.0+ ARM64

bithuman-1.18.0-cp39-cp39-manylinux_2_28_x86_64.whl (14.5 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ x86-64

bithuman-1.18.0-cp39-cp39-manylinux_2_28_aarch64.whl (13.4 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ ARM64

bithuman-1.18.0-cp39-cp39-macosx_26_0_arm64.whl (23.3 MB view details)

Uploaded CPython 3.9macOS 26.0+ ARM64

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fe69d46676a1248beb45ded8da26c6e6f2dccd66a459c9e0b9bf837f1c920c0b
MD5 2a899839241dd25cf5fc32d05e8e57e9
BLAKE2b-256 6b92221fbf07aded84d6fe89847e8a994b4e65f2a49e54dc8df252671e0f1e60

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8e1c23614ea7c11e7e73a9de1982c71beb947d6d697145e8d6ae74fa746cbd8d
MD5 f4d5f4ce3d36946a2face8ddc7a20d33
BLAKE2b-256 334326ff8cbddee5f994dc2af57f1251af7d50b477f98fdce1bca157a7f2d76a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp313-cp313-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 6ab0bad46e95ce6232f174f8f90597538d50dbc0ba0dee79ccf03db052242215
MD5 b82c4da403b5343fced1bc876fc7c79b
BLAKE2b-256 576cadcc93af12821fbfe86ffaefa55e2874bcc06a60319814257c7f25519cb8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d26f5f75eb5b44b52ad821ce0cef66064781a71c8e068bba2292b78984965676
MD5 d86d92b18833b2dbb7d76af8fd3ae908
BLAKE2b-256 d979fb72dcf055f1f1a2278599ea8acd34e000ee472a06539b8bf1ac9a846488

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 d0e44f680a62aedb2cd0d958baf56c9b7a8b01760c5b8ae99a68d98195d83680
MD5 e8871fc7b59d5f2e693e45ba55b623c3
BLAKE2b-256 02ccbe96885a7fe42b6712fc1f42112440266a78e0c00521dd6439f1c1cb7bee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp312-cp312-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 93095e9e2cccf3c0a927fdf887ee1c60d8c162e030d34d518de2137f2927b04f
MD5 e089581feaa12c7cebdb385ddf19e15e
BLAKE2b-256 de787541a705f0998292a711ca205268b8bd3999e52069e342ec1bb2277f7d8b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 46634796e9947f0634732e33db72e921ad20d2a33d7d7abc46f8bfa269283c09
MD5 9358af49ee95acfd9948c5a60b200ccd
BLAKE2b-256 44b6aa3ed46e95a520bb724f53fcd5be73fec907be8bb017f1f26dffaea3d954

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3890fa1cd9c51115d2b018a620014cc3180feb55b8d4f47b8da91c0df3c85db5
MD5 24f3e2340d24a24d2801ff2bb4ed852a
BLAKE2b-256 287982b4cfd323042f90410da39f3b0d93e71653dc8db75fb420c279bf813ba2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp311-cp311-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 43072945954ea93379b3efc998dcaf8b5b4e3aca4b5e0c4490e5654b30e2b67c
MD5 60e18067d287f48d2b84f593fdef44ac
BLAKE2b-256 d0b44e649c15cdaae4a630cf785c7cffe8e817014c53508677ae1e114d00e268

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 679e15dcf2dfeecc7b13b50842941424285ce8b3cbbcb9fb66e0322c8c73401b
MD5 86fec7999fa5a5a858546e057c8327c3
BLAKE2b-256 f82a244cfb60c2ca21deab4d8732a9a945bdc20922a77f3d9eef9d9b12fd3011

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 7f3f74d457246c94c08818e5db56dc97c58133da9735de81680f571efc4cfee6
MD5 cf65eae44b78d79ec1514595a8f064f6
BLAKE2b-256 fd5a73a7bcb340037873daab362b535709bf020239debdb2da72f3c241c63847

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp310-cp310-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 a7bef7a933e95da2b48021c9e092c52cf59c31fb83eeaa353c69be7a8af692d9
MD5 11a5cd5742e9de9d30be515de8bc136a
BLAKE2b-256 6fce0d51f46b04a61ebe66af1c81bbaa0854e7ee6e07276fd1f8515750cf2896

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 5d33af2f1fce380b297e50aade63b429310fa6f172f71509223a844dc7c8f0b9
MD5 f0a361791975fb97ce47db8ef7ace7f0
BLAKE2b-256 173ffd326ce6f44a35fc470bff6b7f3b4ac57bfcc99d10125ae56659aca26c10

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp39-cp39-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 506777bcac8a21efa841f17069700d5304fa4410fd902df57e7210480be6d318
MD5 cded14673fba590c3b7d86d4cbebab07
BLAKE2b-256 36b292c129fddfd4928bc96137b6122ba8b278ba761ad30c2fb5a645bc95dfb3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.0-cp39-cp39-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 a3aa3c1d3be61b04faae94248e5a960257ad4c470df5e8c086fdf1477b1863b8
MD5 91b516f54769e48ba00434f439960dd0
BLAKE2b-256 5410800f187b1cafde1639a6096ab8a3e814fedb9066a09c683174b157dfad39

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