Turn a ragged batch of token sequences, stored back to back in one flat array, into a padded batch and its mask, with the padding work compiled by jax.jit once per bucket length.
tokens is a flat int32 JAX array that holds the B sequences of the batch one after another, and lengths is an int32 JAX array of shape (B,) whose entry lengths[b] is the number of tokens in sequence b. Writing ℓb for lengths[b], sequence b starts at the flat position
sb=c=0∑b−1ℓc,and occupies positions sb to sb+ℓb−1.
buckets is a Python list of positive ints in any order, and pad_id is a Python int. The function is called as pad_to_bucket(tokens, lengths, buckets, pad_id).
The padded length L is the smallest value in buckets that is at least the longest length. In the output, row b and column j hold tokens[sb+j] when j<ℓb and pad_id otherwise, and the mask is True exactly where j<ℓb.
Return a dict with exactly two keys. tokens is an int32 JAX array of shape (B, L), and mask is a bool JAX array of shape (B, L).
Input: tokens = [5,6,7,8,9], lengths = [3,2], buckets = [4,8], pad_id = 0
Output: {"tokens":[[5,6,7,0],[8,9,0,0]],"mask":[[true,true,true,false],[true,true,false,false]]}
Explanation: The lengths add up to the 5 flat tokens, so the rows start at offsets 0 and 3. The longest sequence has 3 tokens and 4 is the smallest bucket that fits it, so both rows are padded with 0 up to length 4.
Input: tokens = [1,2,3,4,5,6], lengths = [5,1], buckets = [16,4,8], pad_id = -1
Output: {"tokens":[[1,2,3,4,5,-1,-1,-1],[6,-1,-1,-1,-1,-1,-1,-1]],"mask":[[true,true,true,true,true,false,false,false],[true,false,false,false,false,false,false,false]]}
Input: tokens = [0,3,0,0,2], lengths = [4,0,1], buckets = [2,4,6], pad_id = 0
Output: {"tokens":[[0,3,0,0],[0,0,0,0],[2,0,0,0]],"mask":[[true,true,true,true],[false,false,false,false],[true,false,false,false]]}
jax.jit(f, static_argnames="length") hands length to f as a Python int, so jnp.arange(length) has a fixed size.
jnp.cumsum(lengths) returns inclusive running totals, and a row starts where the earlier rows' total ends.
tokens[index] with a (B, L) integer array gathers all slots at once, and jnp.clip bounds index.
Accepts: array
Accepts: array
Accepts: array
Accepts: integer
Turn a ragged batch of token sequences, stored back to back in one flat array, into a padded batch and its mask, with the padding work compiled by jax.jit once per bucket length.
tokens is a flat int32 JAX array that holds the B sequences of the batch one after another, and lengths is an int32 JAX array of shape (B,) whose entry lengths[b] is the number of tokens in sequence b. Writing ℓb for lengths[b], sequence b starts at the flat position
sb=c=0∑b−1ℓc,and occupies positions sb to sb+ℓb−1.
buckets is a Python list of positive ints in any order, and pad_id is a Python int. The function is called as pad_to_bucket(tokens, lengths, buckets, pad_id).
The padded length L is the smallest value in buckets that is at least the longest length. In the output, row b and column j hold tokens[sb+j] when j<ℓb and pad_id otherwise, and the mask is True exactly where j<ℓb.
Return a dict with exactly two keys. tokens is an int32 JAX array of shape (B, L), and mask is a bool JAX array of shape (B, L).
Input: tokens = [5,6,7,8,9], lengths = [3,2], buckets = [4,8], pad_id = 0
Output: {"tokens":[[5,6,7,0],[8,9,0,0]],"mask":[[true,true,true,false],[true,true,false,false]]}
Explanation: The lengths add up to the 5 flat tokens, so the rows start at offsets 0 and 3. The longest sequence has 3 tokens and 4 is the smallest bucket that fits it, so both rows are padded with 0 up to length 4.
Input: tokens = [1,2,3,4,5,6], lengths = [5,1], buckets = [16,4,8], pad_id = -1
Output: {"tokens":[[1,2,3,4,5,-1,-1,-1],[6,-1,-1,-1,-1,-1,-1,-1]],"mask":[[true,true,true,true,true,false,false,false],[true,false,false,false,false,false,false,false]]}
Input: tokens = [0,3,0,0,2], lengths = [4,0,1], buckets = [2,4,6], pad_id = 0
Output: {"tokens":[[0,3,0,0],[0,0,0,0],[2,0,0,0]],"mask":[[true,true,true,true],[false,false,false,false],[true,false,false,false]]}
jax.jit(f, static_argnames="length") hands length to f as a Python int, so jnp.arange(length) has a fixed size.
jnp.cumsum(lengths) returns inclusive running totals, and a row starts where the earlier rows' total ends.
tokens[index] with a (B, L) integer array gathers all slots at once, and jnp.clip bounds index.
Accepts: array
Accepts: array
Accepts: array
Accepts: integer