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

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

bithuman-1.18.4-cp313-cp313-manylinux_2_28_aarch64.whl (15.5 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

bithuman-1.18.4-cp313-cp313-macosx_26_0_arm64.whl (25.3 MB view details)

Uploaded CPython 3.13macOS 26.0+ ARM64

bithuman-1.18.4-cp312-cp312-manylinux_2_28_x86_64.whl (16.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

bithuman-1.18.4-cp312-cp312-manylinux_2_28_aarch64.whl (15.5 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

bithuman-1.18.4-cp312-cp312-macosx_26_0_arm64.whl (25.3 MB view details)

Uploaded CPython 3.12macOS 26.0+ ARM64

bithuman-1.18.4-cp311-cp311-manylinux_2_28_x86_64.whl (16.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

bithuman-1.18.4-cp311-cp311-manylinux_2_28_aarch64.whl (15.5 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

bithuman-1.18.4-cp311-cp311-macosx_26_0_arm64.whl (25.3 MB view details)

Uploaded CPython 3.11macOS 26.0+ ARM64

bithuman-1.18.4-cp310-cp310-manylinux_2_28_x86_64.whl (16.6 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

bithuman-1.18.4-cp310-cp310-manylinux_2_28_aarch64.whl (15.5 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

bithuman-1.18.4-cp310-cp310-macosx_26_0_arm64.whl (25.3 MB view details)

Uploaded CPython 3.10macOS 26.0+ ARM64

bithuman-1.18.4-cp39-cp39-manylinux_2_28_x86_64.whl (16.6 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ x86-64

bithuman-1.18.4-cp39-cp39-manylinux_2_28_aarch64.whl (15.5 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.28+ ARM64

bithuman-1.18.4-cp39-cp39-macosx_26_0_arm64.whl (25.3 MB view details)

Uploaded CPython 3.9macOS 26.0+ ARM64

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 36474166b3c996f943d37dfbfac7f6d798ddc9a6edb6580f200198a1b27eafdd
MD5 53f5b6109583e6e4d5eac1deb41304d5
BLAKE2b-256 76fd3a8425f80f29c78693afab3cacce1ac9060059b40f21dd89339d779de2c4

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3b1dfa147cfefd0bf5c811bc31f486d220df77bde0dafb3064619d15b1a166fa
MD5 8039a2a76a3ebdec8f5c89fab18ff533
BLAKE2b-256 e3adf498848384286ddcaa99649153ec5bcdaa69879076779da9accbed28997b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp313-cp313-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 59f8a997be58493b503032146ec78fa9bab87253d51e5ff7d8641dcbac315d5c
MD5 70db7be6239c8740e793a7f5b3a86148
BLAKE2b-256 7ad5f49a460cf5e5ec8ded547b163c0fba8a8a9c2ee4a89412ec3a1487c7bd07

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 6c76b182724bc2d787e2427ad1f824add3aa79cfb500857ef266e7896ed95af1
MD5 a3010a944de63993df7c646432a981ec
BLAKE2b-256 6eec0b24f7773925423adceee9e11055e5d18ed0a52ccbcc5988314e31cab8f6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 d4260fbd598b4fa45b919ddc76e00a627a747919190d816036c447f583e18891
MD5 8030255378358f01cc22c326803f6b18
BLAKE2b-256 dbfc1e4dbf708c9708403f15f5790ba7ebcaf274b4474dbbf4e2a585c4f0ece3

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp312-cp312-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 72325275fc377120cc2048a205d20a5fd8c8cf3326fbf5499a1507144ca29302
MD5 76e8191d1fb502225658d5ec9081ea64
BLAKE2b-256 71f270385f462bb374cb63b051ab0cf2d203317e1770b212971049a249c18a38

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7c352848323d19fe78091b0c29112d67d9217e44b7ff1341d63f50ebdf2dddd0
MD5 edbded32d60f200092906b3e842c6d2d
BLAKE2b-256 7d9afbc5f351b290d53b65857feb9632774e634bd833a796cdac0f7c32087008

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c9839a50916a0693062c452a940711d91fd9b803cd366b180878c7ccc4f4bc45
MD5 ce95717dd3ebec8ee5de01c1a0fa0839
BLAKE2b-256 00201e085d8a4b13d6ebc33dd4c5f79ffbd739c16737ea0e2478870d00cb174b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp311-cp311-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 11d53fc899beb46b36fdc639203bfda052997e6ca40637ce5b9eec82228bc280
MD5 26894ea9c81f152351f402376b2f0c51
BLAKE2b-256 e98ab0a36d3988d093febc817238ee773a20ec251e8ce3e454da96252124f73e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d8cec9086e9ffd08545129b2f236e8da1e97843582121b35e245562c17428092
MD5 39ab88bff7bec34119badf5aa635b91f
BLAKE2b-256 96fa5e5a6b879bd9a7b39e2575930e09d29e2931eb1cffd1b5f24ada8d809348

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 04b439646bebb5a732d3a4ec608723fdf28550f5dd1a224486578b92205a223e
MD5 3ad81f9f171625a75f4d232649bf50e6
BLAKE2b-256 fded9b45784ca8fa6ec5475e2c50493e47745bc9b750bf3a37f5ab25313b61bd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp310-cp310-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 25721864678bb679b87b8e9ecc6dab7c24a6b32d366e83c2be0abffe3b6899de
MD5 643ee1eb1c400e9202bd17560d65d229
BLAKE2b-256 861a4facfb7bfb55f097bce2b2686b0722138001da4e96c271df0e3374db1c2c

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 137be66a9071ae3265cb88d80920d9dcb0df22fda3856953af20f0482895a4f9
MD5 74c41a86bd6b37e7d61169e49d0b7366
BLAKE2b-256 43298554b9edb35b178fc268e5294e4d2138d8fdfc547c2c80de643241581aa1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp39-cp39-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 fa0cbeb3bb9d81fd6432a51dff7e75734cb37c5a6e23e4b57f9200d9f170fa6b
MD5 1139ee8742bb3653e9944cecb4deb6b2
BLAKE2b-256 63ed6c29f7cfcbd144796cbea1a60cb8014dbf7152647006c0599ee25b91a209

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.18.4-cp39-cp39-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 47c9f26debf7ffa72017e6c17fb2c91672ae5991e742422eac3886178c6098f2
MD5 2e943f5ad433e35cb8ed900226337716
BLAKE2b-256 fea93e9a154f35043f4c7198f63c2b6b27e1c3b39dcbd0db3c0af532fda86e37

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