Metadata-Version: 2.5
Name: pantogloss
Version: 0.2.0
Summary: TensorFlow/Keras many-to-English machine translation
Project-URL: Homepage, https://github.com/chrismattmann/pantogloss
Project-URL: Repository, https://github.com/chrismattmann/pantogloss
Project-URL: Model repository, https://huggingface.co/chrismattmann/pantogloss-500-en
Project-URL: Issues, https://github.com/chrismattmann/pantogloss/issues
Author: Chris A. Mattmann
License: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: keras,machine translation,multilingual,tensorflow
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Requires-Dist: huggingface-hub<2,>=0.26
Requires-Dist: nlcodec<0.6,>=0.5
Requires-Dist: numpy<3,>=1.26
Requires-Dist: sacremoses<0.3,>=0.2
Requires-Dist: tensorflow<2.19,>=2.18
Provides-Extra: conversion
Requires-Dist: ruamel-yaml>=0.17; extra == 'conversion'
Requires-Dist: torch<3,>=2.2; extra == 'conversion'
Provides-Extra: cuda
Requires-Dist: tensorflow[and-cuda]<2.19,>=2.18; extra == 'cuda'
Provides-Extra: metal
Requires-Dist: tensorflow-metal<1.3,>=1.2; (sys_platform == 'darwin' and platform_machine == 'arm64') and extra == 'metal'
Requires-Dist: tensorflow<2.19,>=2.18; extra == 'metal'
Provides-Extra: test
Requires-Dist: pytest-cov<8,>=5; extra == 'test'
Requires-Dist: pytest<10,>=8; extra == 'test'
Description-Content-Type: text/markdown

# Pantogloss

Pantogloss is a TensorFlow/Keras many-to-English machine-translation library.
Its first model, `pantogloss-500-en`, was converted and numerically validated
from the model described in *Many-to-English Machine Translation
Tools, Data, and Pretrained Models* (ACL-IJCNLP 2021).

The Python package is distributed through PyPI, while the initial model is kept
in a separate private Hugging Face repository. Installing Pantogloss does not
grant model access; users must be authorized for
`chrismattmann/pantogloss-500-en` and authenticate with `hf auth login`.

The codebase and converted model are licensed under Apache-2.0. This repository
is private during initial development.

## Intended API

```python
from pantogloss import Translator

translator = Translator.from_pretrained("pantogloss-500-en")
print(translator.translate("Comment allez-vous ?"))
```

RTG-compatible beam search is available without changing the return type:

```python
print(
    translator.translate(
        "Comment allez-vous ?",
        beam_size=4,
        length_penalty=0.6,
    )
)
```

Pantogloss selects the first TensorFlow GPU automatically and enables memory
growth. Device choice can also be made explicit:

```python
translator = Translator.from_pretrained("pantogloss-500-en", device="gpu")
print(translator.device_info)
```

Using `device="gpu"` fails clearly if TensorFlow cannot see a GPU; use
`device="cpu"` to force CPU inference.

Greedy translation uses an encode-once, graph-compiled TensorFlow decoding loop
with decoder self-attention and cross-attention key/value caches by default. If
a TensorFlow backend cannot compile that loop, Pantogloss falls back to the
equivalent eager decoder. The fallback can also be selected explicitly for
diagnostics or parity testing:

```python
translator = Translator.from_pretrained(
    "pantogloss-500-en", compiled_decode=False
)
```

Install the accelerator backend for the machine:

```bash
# Linux with an NVIDIA GPU
pip install 'pantogloss[cuda]'

# Apple Silicon
pip install 'pantogloss[metal]'
```

Both use the same `device="auto"` or `device="gpu"` Python API. The CUDA extra
does not install or replace the host NVIDIA driver. The Metal extra uses Apple's
TensorFlow PluggableDevice and the TensorFlow 2.18 runtime combination validated
by the Bytewise project.

The model is stored separately in the private Hugging Face repository
`chrismattmann/pantogloss-500-en`; it is never included in the Python wheel.

## Command line

The `pantogloss` command loads the model once and supports arguments, files, and
line-oriented Unix pipelines:

```bash
pantogloss info
pantogloss translate "Comment allez-vous ?"
printf 'Hola señor\nWie geht es Ihnen?\n' | pantogloss translate --device gpu
pantogloss translate --input source.txt --output english.txt --batch-size 16
pantogloss translate --beam-size 4 --length-penalty 0.6 "Hola señor"
```

Use `--json` for JSON Lines output and `--offline` to require an already cached
model snapshot. Translation data goes to stdout (or `--output`); model and device
diagnostics are suppressed by default so pipelines remain clean. Use `--verbose`
for Pantogloss loading progress or `--tensorflow-logs` for TensorFlow, CUDA, and
Metal startup diagnostics.

## Development status

The complete 307-variable Keras model has been converted locally from all 308
learned PyTorch tensors (the target embedding and output projection are tied).
Greedy parity against the archived RTG implementation passes across a ten-language
batch: token IDs and translations match exactly, while final logits have a
maximum absolute error of 1.24e-5. With the original beam size 4 and length
penalty 0.6, all decoded four-best candidate sets match. One near-tied example
changes top rank because of framework floating-point ordering. Model version
0.1.0 is released in the private Hugging Face repository at an immutable commit.

The source model and generated artifacts stay under the ignored `artifacts/`
directory. To reproduce conversion after acquiring the source archive:

```bash
python tools/convert_rtg_checkpoint.py \
  artifacts/source/rtg500eng-tfm9L6L768d-bsz720k-stp200k-ens05 \
  artifacts/converted/pantogloss-500-en-candidate
```

Run the reference parity harness with:

```bash
CUDA_VISIBLE_DEVICES=-1 python tools/check_parity.py \
  artifacts/source/rtg500eng-tfm9L6L768d-bsz720k-stp200k-ens05 \
  artifacts/converted/pantogloss-500-en-candidate
```

To require and verify real GPU placement:

```bash
python tools/check_gpu.py artifacts/converted/pantogloss-500-en-candidate
```

## Apple Silicon validation

Pantogloss uses the same hardware-neutral GPU API for CUDA and Metal. On an
M-series Mac with Python 3.12 and Xcode command-line tools installed:

```bash
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e '.[metal,test]'
hf auth login
python tools/check_platform.py --device cpu
python tools/check_platform.py --device gpu
python tools/benchmark_inference.py --device gpu --runs 5
```

The portable platform report identifies the selected backend as `cpu`, `cuda`,
or `metal`, verifies the first model variable's actual TensorFlow placement,
and runs a real translation. Metal placement and inference are validated on an
Apple M3 Max with TensorFlow 2.18.1. Before compiled decoding, a short batch-one
sentence had warmed medians of 0.545 seconds on CPU and 0.633 seconds on Metal.

## Decoding benchmark

Use the same input repeated into batches of 1, 8, 16, and 32:

```bash
for batch in 1 8 16 32; do
  python tools/benchmark_inference.py --device gpu --runs 5 \
    --batch-size "$batch"
done
```

The August 2026 TensorFlow 2.18.1 validation produced the following warmed
throughput. CPU and CUDA were measured on Linux; Metal was measured on an Apple
M3 Max with 128 GB unified memory.

| Batch size | CPU | CUDA (RTX 3080 Ti Laptop) | Metal (M3 Max) |
|---:|---:|---:|---:|
| 1 | 11.6/s | 14.2/s | 3.83/s |
| 8 | 62.1/s | 94.9/s | 29.15/s |
| 16 | 96.8/s | 160.6/s | 60.20/s |
| 32 | 143.0/s | 330.0/s | 115.28/s |

The M3 Max batch-one median was 0.253 seconds with compiled cached decoding,
down from the pre-compilation measurement of 0.633 seconds. Cold model load and
first-call graph compilation are reported separately from the warmed runs.

The benchmark JSON also reports total process peak RSS and, where supported by
the TensorFlow backend, allocator current memory, peak memory, and the peak
increment above its post-warmup baseline. At batch 32, CUDA's allocator rose by
22.5 MiB above the 2,114.5 MiB model baseline. Peak process RSS was approximately
8.4 GiB on CPU, 5.9 GiB with CUDA, and 4.0 GiB with Metal. TensorFlow Metal 1.2
reports zero for its allocator counters, so process RSS is the meaningful Metal
memory measurement.
