Any-to-Any
MLX
Safetensors
gemma4
mlx-vlm
rlcd
multimodal
classification
parallel-inference
image-text-to-text
audio
video
4-bit precision
Instructions to use larkooo/gemma-e2b-rlcd with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- MLX
How to use larkooo/gemma-e2b-rlcd with MLX:
# Download the model from the Hub pip install huggingface_hub[hf_xet] huggingface-cli download --local-dir gemma-e2b-rlcd larkooo/gemma-e2b-rlcd
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- LM Studio
- Atomic Chat
| from types import SimpleNamespace | |
| import pytest | |
| from gemma_rlcd.cached_backend import CachedMLXBackend, PreparedState | |
| from gemma_rlcd.core import ScoringRequest | |
| mx = pytest.importorskip("mlx.core") | |
| cache_module = pytest.importorskip("mlx_vlm.models.cache") | |
| KVCache = cache_module.KVCache | |
| RotatingKVCache = cache_module.RotatingKVCache | |
| def test_cache_forks_preserve_prefix_and_isolate_rows(kind): | |
| backend = CachedMLXBackend.__new__(CachedMLXBackend) | |
| backend.mx = mx | |
| original = KVCache() if kind == "full" else RotatingKVCache(max_size=8) | |
| keys = mx.arange(48).reshape(1, 1, 12, 4).astype(mx.float32) | |
| original.update_and_fetch(keys, keys + 100) | |
| before_keys, before_values = mx.array(original.keys), mx.array(original.values) | |
| before_offset = original.offset | |
| before_index = getattr(original, "_idx", None) | |
| branch = backend.fork_cache([original], 3)[0] | |
| updates = mx.array([1000, 2000, 3000], dtype=mx.float32)[:, None, None, None] | |
| updates = mx.broadcast_to(updates, (3, 1, 2, 4)) | |
| output_keys, _ = branch.update_and_fetch(updates, updates + 50) | |
| mx.eval(output_keys, original.keys, before_keys) | |
| assert original.offset == before_offset | |
| assert getattr(original, "_idx", None) == before_index | |
| assert bool(mx.array_equal(original.keys, before_keys).item()) | |
| assert bool(mx.array_equal(original.values, before_values).item()) | |
| assert output_keys[:, 0, -1, 0].tolist() == [1000, 2000, 3000] | |
| assert branch.offset == before_offset + 2 | |
| def test_unrecognized_cache_type_fails_explicitly(): | |
| backend = CachedMLXBackend.__new__(CachedMLXBackend) | |
| backend.mx = mx | |
| with pytest.raises(TypeError, match="Unsupported cache type"): | |
| backend.fork_cache([object()], 2) | |
| def test_batched_trim_selects_each_real_answer_before_padding(): | |
| backend = CachedMLXBackend.__new__(CachedMLXBackend) | |
| backend.mx = mx | |
| backend.branch_batch_size = 4 | |
| backend.last_stats = {} | |
| backend.tokenizer = SimpleNamespace(pad_token_id=0) | |
| backend._ids = {"A": 0, "B": 1} | |
| backend.fork_cache = lambda prefix, size: [] | |
| calls = [] | |
| def decoder(*, inputs, cache, logits_to_keep): | |
| calls.append((inputs.shape, logits_to_keep)) | |
| return inputs[:, -logits_to_keep:, None].astype(mx.float32) | |
| backend.model = SimpleNamespace( | |
| language_model=SimpleNamespace( | |
| model=decoder, | |
| logits_from_hidden=lambda hidden: mx.concatenate([hidden, -hidden], axis=-1), | |
| ) | |
| ) | |
| prepared = PreparedState({}, [[2, 3, 7, 9], [1, 11], [5, 13, 17]], 100) | |
| requests = [ScoringRequest("test", ("A", "B"))] * 3 | |
| scores = backend.branches(prepared, [], requests) | |
| assert calls == [((3, 4), 3)] | |
| assert [score.logits for score in scores] == [(9, -9), (11, -11), (17, -17)] | |
| assert [score.input_tokens for score in scores] == [104, 102, 103] | |
| assert backend.last_stats["branch_batch_sizes"] == [3] | |
| def test_gathered_causal_mask_preserves_each_answer_position(): | |
| from gemma_rlcd.answer_positions import select_answer_mask | |
| mask = select_answer_mask("causal", mx.array([3, 1]), 4, 10) | |
| assert mask.shape == (2, 1, 1, 10) | |
| assert mask.sum(axis=-1).tolist() == [[[10]], [[8]]] | |
| def test_gathered_window_mask_preserves_existing_mask(batched): | |
| from gemma_rlcd.answer_positions import select_answer_mask | |
| mask = (mx.arange(10)[None, :] <= mx.arange(6, 10)[:, None]) & ( | |
| mx.arange(10)[None, :] >= mx.arange(4, 8)[:, None] | |
| ) | |
| if batched: | |
| mask = mask[None, None, :, :] | |
| selected = select_answer_mask(mask, mx.array([3, 1]), 4, 10) | |
| assert selected.shape == (2, 1, 1, 10) | |
| assert selected[0, 0, 0].tolist() == [False] * 7 + [True] * 3 | |
| assert selected[1, 0, 0].tolist() == [False] * 5 + [True] * 3 + [False] * 2 | |