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

Uploaded CPython 3.13manylinux: glibc 2.28+ x86-64

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

Uploaded CPython 3.13manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.13macOS 26.0+ ARM64

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

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

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

Uploaded CPython 3.12manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.12macOS 26.0+ ARM64

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

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

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

Uploaded CPython 3.11manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.11macOS 26.0+ ARM64

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

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

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

Uploaded CPython 3.10manylinux: glibc 2.28+ ARM64

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

Uploaded CPython 3.10macOS 26.0+ ARM64

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

Uploaded CPython 3.9manylinux: glibc 2.28+ x86-64

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

Uploaded CPython 3.9manylinux: glibc 2.28+ ARM64

bithuman-1.17.6-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.17.6-cp313-cp313-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for bithuman-1.17.6-cp313-cp313-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3c5667f00f3284d30a0faa3b71ed62ae4d633e3a2e1ab03b12eb821d43555b4a
MD5 c454fe2b9fe9c87a7d408bbc393d93c6
BLAKE2b-256 ca5c775f4ae1425b981bb2b5e8f438a5bc5bbff8be34886b011f2147d93416ce

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp313-cp313-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 58e767522359492a31b9419ba8ff083055cc94c0c59913d0ecc4739b98908776
MD5 e0df89385f45186c1dd51475670ec9ee
BLAKE2b-256 d789f384e67f90bd04224c3fd194ccc0521fe62ce2c79d42bca742bf98c70db8

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp313-cp313-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 5ffe8218ad01271bf6e44e17e1ecfd54816ce2fe66846b294c886af611d99394
MD5 c9eded306bb42279b5e7dd8d68b14ee8
BLAKE2b-256 26d3eeb21c4d3a8066b58807cc2b306405812d43b9997a01fa68f706a68c539e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 cdb0302636b95ba74cd81927b5eed129a7b8944234a585d9ce26503b052da2d5
MD5 b7265163940e812abf09c0f33a8d65a5
BLAKE2b-256 4051fb5a8c039b7908e936a258098970202b6c636bb83d620f56ea4d6ae9b583

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp312-cp312-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 4ed6f917ac091f82105e5b04b5f2e32b9c610c93c34b345146e6eff540877f0f
MD5 dc8252c361057a50fa4ea4e870114961
BLAKE2b-256 c89381b21bc788e797d16b306b53820a54881fc62ab75633b1bc41489aa1943a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp312-cp312-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 5bfb640ee495b3d67779452dbdafe42f0ed0f5b6abb1400d22b848fa4b441144
MD5 f5aa6d0d7c74ac503ce711af586b6512
BLAKE2b-256 9a3d58a5a279dd69cab0241e96443bf7d8f4c2490a1a3ecfcd487cfb7d9973c9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 76bb6766e5a96b00d5b4efb2196fa6fc88f62ea51487820c7f72816575e47529
MD5 d535a888b1b4ae21629d6cdc21182b73
BLAKE2b-256 de2baf700359997140113d480368bd0802960fbc33e66c15a47942d7e80aeff6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp311-cp311-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 85e797dff0fb8b568bc5579b3db02d54b28fb60c0755e17cecd861003d607cc0
MD5 67c585fec08cb48bc1ab77481d62ff5c
BLAKE2b-256 be3610843f9922ff356ac070df12239046ad88a75f6ea40e15d744c97881ba2f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp311-cp311-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 dfd6c16adcc04c5f54385d45c13e351cc12b6a4f24a6f7d237879853405d636f
MD5 915033b217895855b4a7a82c6318b56e
BLAKE2b-256 e8059180aeb3c0f063f0a26c30bab911f887e50561cc60ebc105e89c0982c775

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 c241cce52c99c04042f172bae2386ae9bfe53ca9fc2a6c8438ce913cbdf4c7f4
MD5 84254e085fd13533971fe38f5718f7a5
BLAKE2b-256 76554cb8e1e68a7bf4a426427708439223b39cf2818e344625f480691b6c11f0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp310-cp310-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0cd2d1e0b096a2685daebb4d282c6fde3123771ee9556663296c0f161aa665bf
MD5 1531fde488988189c5bb0861898fdc0b
BLAKE2b-256 24b7746a817cd0dd8e6f24e369b58b50010d9ba635561b153f01bdd2ca549cba

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp310-cp310-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 7184146aad06be9115ea81c6bfc90237b59f6fed8179bacd712baeb40d7afcaa
MD5 2318ca5d63178fd48a91d573cb1ae478
BLAKE2b-256 8fa718992d43f002c287b20fca3a662e3e0acba29fe4069915be462a6ac52932

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp39-cp39-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 feb487fa45165d96141e120c5d9f412e11f4c8087f1d13346ea3e65c82a7c798
MD5 69509888343083f47eb75934c2294365
BLAKE2b-256 8ef70ea41924e88358de50563b50a94843abb6dbae7079c79ab212680d7cee17

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp39-cp39-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 ea80acfc85d2df407d9b9b972e5ed56240fd8312fa503c7159921a4c79347757
MD5 c5ae51eef1695f60c06741028d41518e
BLAKE2b-256 85d0b85f89d1f84ecfffef1bb73a52b8deccc354b4afd67b9eb672deba40f43f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for bithuman-1.17.6-cp39-cp39-macosx_26_0_arm64.whl
Algorithm Hash digest
SHA256 bf1d068899fa942d888203c31624c67ef78acd4eaadfb9edfbff958bb96e1fd6
MD5 f209fba30ca59f9d18528f0acd24d169
BLAKE2b-256 15c8a9820c7f992d9fe6eec21efb5d49d097ea6d6228b678feebcf4ebe6b129f

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