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.0-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.0-cp314-cp314-manylinux_2_28_aarch64.whl (17.1 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.14macOS 26.0+ ARM64

bithuman-1.19.0-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.0-cp313-cp313-manylinux_2_28_aarch64.whl (17.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.13macOS 26.0+ ARM64

bithuman-1.19.0-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.0-cp312-cp312-manylinux_2_28_aarch64.whl (17.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.12macOS 26.0+ ARM64

bithuman-1.19.0-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.0-cp311-cp311-manylinux_2_28_aarch64.whl (17.1 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.11macOS 26.0+ ARM64

bithuman-1.19.0-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.0-cp310-cp310-manylinux_2_28_aarch64.whl (17.0 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.10macOS 26.0+ ARM64

bithuman-1.19.0-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.0-cp39-cp39-manylinux_2_28_aarch64.whl (17.0 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ ARM64

bithuman-1.19.0-cp39-cp39-macosx_26_0_arm64.whl (26.8 MB view details)

Uploaded CPython 3.9macOS 26.0+ ARM64

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp314-cp314-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e00a89eb7cd5cbd4ad66abd6491718680b410e5544cb758170bb2d076ec842fe
MD5 711a4a32bc775ded6ccc18dec638f7e5
BLAKE2b-256 6295946347cc0c7fd77bd002f41ac50d0e04a273b5c5cd185ac13539f30541f7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp314-cp314-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 9e1f96733de68b87f711d80e768d4d4f20a9a44d54c3eff0b5c62defd24be019
MD5 5f442745ddd9f19f723188006368ebda
BLAKE2b-256 a2da463ce34ac3c83d7395329ac817f26f8c2105ccf61b7e2925e6dfda227f39

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp314-cp314-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 47eaea65331ec6c27b4f5dcb2ca35bc5cbe326e2978777a3400178ab0bfbea9b
MD5 714a5f1daa672eb4c9f932fb7f6953ac
BLAKE2b-256 9378240715bbfdc349aa65957ddca9ee34e5376ba41a611ec812335c6d75b341

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 30ebfb437ae6c110cff1a6de42166f4334eff72816665158914c16c912681212
MD5 d7ab249cfef8a1002af2a4bdb5adc67a
BLAKE2b-256 764411fcefec9e020bc76dc425eafca84f524bf2b33b7235c382d319889feba8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 18f7aa9eb39e3b8b52af71facc1004e0ddc03de6ca7fbba0a372c718a4d044e3
MD5 85ca03b9937288b4d6c24831e3c42f7e
BLAKE2b-256 a130c1a3d48c4d6e23550f4b2fd507cdf77cfe76a08882d90b0d20f938777df9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp313-cp313-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 d2e919f52885f5f23a14f2ce45d8dba3f368bb1402672e580e6a83e2b8d16e59
MD5 2473b7df5e19109bcbf4af7e5d18daf1
BLAKE2b-256 2b436dd63af571639fa4984deca46b29f3b325d900917fc791f91929f39a0321

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 8769c1250d3d4918fa1532398ae0ed678c8c43926637b015cc117b4f22c25426
MD5 5a40a30fdaf40e06443f938ae5ed008d
BLAKE2b-256 1da92719ede695f505e46c2ab363f7fb8c9d386b61454a2a32a92cbbde0704a2

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 631a9eb3c491e5e3aa4c34b69418041eb5ab8739e1fb21257a30a55ed423eb59
MD5 f25c23c4e4d33e9f1fcb095348e59658
BLAKE2b-256 bb72c4decef9576cc786fd95980dcbb46159a5e5b45094b729592d11b060eb0b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp312-cp312-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 376c566109e406a6c9797748360fd679f7c3c769cb1334007bffcf53a6ed374e
MD5 7d48566ff31df6404425a0ab0a736b1d
BLAKE2b-256 b92470f4dbec9c6bbaeb1ec2a29ecf0470f1e4e20ca658a6f2f93a83e16ce133

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 01db371353f534c52fda850b41b534a9a399b52781aa5c864aa50a0b16e408aa
MD5 e57a60c8778b4a16d411f6d133e73617
BLAKE2b-256 24bb0af77407ecbc7022ae1b926cdef07dd2949564133d9087648762a4e0e55e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c548063f32351546dbb92cc123eb53fa759660fd6ee927f566d1fbbed8a32143
MD5 293bd6c65f86a255587cc6c2170085e4
BLAKE2b-256 033f142c7ddc8e7faa07a33a0bb828772ef9f5071bc14f00c727816d875868d0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp311-cp311-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 35f3e3a3cbc956e311de7e3eda3a44b7ad49959af6950c72c7ce3bc6666b06c8
MD5 41ebb23f15135733e1733142ef17b396
BLAKE2b-256 c8680be78ca123ccee750167b7b1c65e29e567741c37aeaa0720a92648624cee

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 03b3ade8c4401d8d9caa2addbb4358b8ec4ed9245e80019946e5cee3705be691
MD5 ad22cca6f8d9b4e11365671bd736dd73
BLAKE2b-256 edd5c2601e6ccea741a366fa3b3de304d187cb23f7bb51f03784185d2a06af46

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 8cc341162f333b10cd4d2907257e739ace9b5c2673f9d6e420a6258bb4c5a9a9
MD5 795ebf6488f87b5afefcc4939d4a1e57
BLAKE2b-256 1fe935d9ec576863cf6a164251d0d5b816e862356701002abf85680d673bb6b7

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp310-cp310-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 a1f9ae0a69adb7350b85930afb9e1ce5abeed7942294db76607225a7b3ba0e02
MD5 484f4bfa009ca5f901ff8b4b1b39a096
BLAKE2b-256 02d4dbd054895728dc221bd84050c9af836395f00efe31aaf5b71fb0e7834660

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 35352c4640acf1d600b07129b10e6d05f10861c9826069e892a667ef4089e269
MD5 ee5973badca33b07e1d3ddb90533188f
BLAKE2b-256 e2eef6938cecce49378b1ab7c01af7c162c920e56f7e84d0e527450288574589

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp39-cp39-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 4f5a5595618f18e9ee6aeb5604379ec434bed896cd72f3db3ceeef63a56e963d
MD5 82b25df3c584659b8c905ab748baac57
BLAKE2b-256 7cc4d4691ff9881f7651a296e50dd24867bfbf33b63ec20bd8620cd96440e4aa

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.19.0-cp39-cp39-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 d11f7ae33a3152be82a5c98a2b4c8417632adda051ea59dc9fff2898ee40c426
MD5 acc30d1262a274e3ee826ae6e54269c6
BLAKE2b-256 9b0a3ba673878cb692bc78f50fb61f10e90359e78347631f2c71d923966e501a

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