StripedHyena

repository·main·Indexed 19 days ago

https://github.com/togethercomputer/stripedhyena

Model and inference code for StripedHyena v0.2.1, a hybrid deep signal processing architecture combining rotary attention and gated convolutions (Hyena blocks). Designed as a high-performance alternative to Transformers, it offers efficient long-context generation for language and biological sequences. The library includes the HyenaInferenceEngine for managing IIR and FIR filters, a Generator class for sequence generation with sampling strategies, and support for models like StripedHyena-Hessian-7B and StripedHyena-Nous-7B.

Tokens
8.5K
Snippets
31
Records
37
Agent score
66%

What's inside stripedhyena

  1. Set up the Standalone StripedHyena Environment

    main

    To run the standalone implementation, you must install the dependencies in requirements.txt and the rotary and normalization kernels from flash_attn.

    It is recommended to use the provided Dockerfile to ensure all requirements and kernels are correctly installed.

    Build and Run with Docker

    1. Build the image:
    docker build --tag sh:test .
    1. Run the container interactively with GPU support:
    docker run -it --gpus all --network="host" --shm-size 900G -v=<path_to_this_repo>:/mnt:rw --rm sh:test
    docker build --tag sh:test .
    docker run -it --gpus all --network="host" --shm-size 900G -v=<path_to_this_repo>:/mnt:rw --rm sh:test
  2. Implement a custom tokenizer using AbstractTokenizer

    main

    If you need to implement a custom tokenization strategy, inherit from AbstractTokenizer. You must implement the following abstract properties and methods:

    • vocab_size (property): The size of the vocabulary.
    • vocab (property): A dictionary mapping text tokens to integer IDs.
    • inv_vocab (property): A dictionary mapping integer IDs to text tokens.
    • tokenize(text) (method): Converts a string into a sequence of tokens.

    Note that detokenize and several special token properties (cls, sep, pad, eod, mask) are provided as stubs that raise NotImplementedError if not overridden.

    from abc import abstractmethod
    from stripedhyena.tokenizer import AbstractTokenizer
    
    class MyCustomTokenizer(AbstractTokenizer):
        def __init__(self, name):
            super().__init__(name)
    
        @property
        def vocab_size(self): 
            return 1000
    
        @property
        def vocab(self): 
            return { ... }
    
        @property
        def inv_vocab(self): 
            return { ... }
    
        def tokenize(self, text):
            # Your implementation here
            pass
    
        def detokenize(self, token_ids):
            # Your implementation here
            pass
  3. Troubleshoot StripedHyena installation and precision

    main

    Flash Attention Issues

    If you encounter issues, ensure you are using a recent version of flash_attn. You can verify this with:

    pip freeze | grep flash-attn

    It should return a version >= 2.0.0.

    Precision Requirements

    StripedHyena is a mixed precision model. To avoid errors or instability, ensure that your poles and residues are kept in float32 precision.

    pip freeze | grep flash-attn
  4. Generate text using the Standalone implementation

    main

    Once the environment is set up, use generate.py to produce text. You will need a configuration file (e.g., ./configs/7b-sh-32k-v1.yml) and a checkpoint path.

    Generation Command

    python generate.py --config_path ./configs/7b-sh-32k-v1.yml \
    --checkpoint_path <path_to_ckpt> --cached_generation \
    --prompt_file ./test_prompt.txt

    Prefill Styles

    When using a prompt_file, you can tune the prefill_style in your config:

    • prefill_style: fft: Standard for generating with prompt.txt.
    • prefill_style: recurrence: Use this for very long prompts to reduce memory usage, though it is slower.
    python generate.py --config_path ./configs/7b-sh-32k-v1.yml \
    --checkpoint_path <path_to_ckpt> --cached_generation \
    --prompt_file ./test_prompt.txt
  5. Generate text using HuggingFace models

    main

    You can use the generate_transformers.py script to run inference using models hosted on HuggingFace.

    Available Model IDs:

    • Base model: togethercomputer/StripedHyena-Hessian-7B
    • Chat model: togethercomputer/StripedHyena-Nous-7B

    Command

    python generate_transformers.py --model-name <model_id> --input-file ./test_prompt.txt
    python generate_transformers.py --model-name <model_id> --input-file ./test_prompt.txt
  6. Swap RoPE in an existing MHA layer with swap_mha_rope

    main

    The swap_mha_rope function allows you to replace the existing Rotary Positional Embedding (RoPE) implementation within a Flash Attention MHA (Multi-Head Attention) module. This is particularly useful for injecting LinearlyScaledRotaryEmbedding into a pre-existing model architecture.

    It automatically detects the dtype and device from the MHA weights and preserves existing RoPE settings like dim, base, and interleaved while applying new configuration via kwargs_new_rope.

    from stripedhyena.positional_embeddings import swap_mha_rope
    
    # Assuming 'mha' is an existing flash_attn.modules.mha.MHA instance
    # Replace existing RoPE with LinearlyScaledRotaryEmbedding and a scaling factor of 2.0
    swap_mha_rope(
        mha,
        new_rope=LinearlyScaledRotaryEmbedding,
        kwargs_new_rope={"scaling_factor": 2.0}
    )
  7. Initialize inference parameters for StripedHyena

    main

    To perform stateful (recurrent) inference, you must initialize a dictionary of inference parameters. This dictionary contains:

    • mha: InferenceParams specifying max_seqlen, max_batch_size, and seqlen_offset.
    • hyena: RecurrentInferenceParams specifying fir_filter_length, state_dim, and seqlen_offset.

    This dictionary is passed into stateful_forward and is updated by the model during the forward pass to track the FIR and IIR states for each layer.

    params_dict = model.initialize_inference_params()
    # params_dict contains keys 'mha' and 'hyena'
  8. Step the FIR filter incrementally with step_fir

    main

    Use step_fir to perform incremental inference on the FIR filter. This is used during the decoding phase after the initial prefill.

    Parameters

    • u: The new input token.
    • fir_state: The state containing the last short_filter_length - 1 elements of previous inputs.
    • weight: Filter weights (expected shape [d, 1, short_filter_len] for SISO/multi-SISO).
    • bias: (Optional) Filter bias.

    Returns

    A tuple of (y, fir_state):

    • y: The new output value.
    • fir_state: The updated state for the next step.
    y, fir_state = engine.step_fir(u, fir_state, weight, bias=bias)
  9. Sample tokens from logits using the sample function

    main

    The sample function performs token sampling from a logits tensor of shape (batch_size, vocab_size). It supports greedy decoding, top-k filtering, top-p (nucleus) filtering, and temperature scaling.

    Arguments

    • logits: A torch.Tensor of shape (batch_size, vocab_size).
    • top_k: The number of highest-probability tokens to keep. If top_k=1, it performs greedy decoding (returning the argmax). If top_k > 0, it restricts sampling to the top-k tokens.
    • top_p: The cumulative probability threshold for nucleus sampling. Must be in the range (0, 1] if used.
    • temperature: A scaling factor applied to logits before softmax. A higher temperature increases randomness, while a lower temperature makes the distribution more peaked.

    Behavior

    1. Cleans logits by replacing NaN, inf, and -inf with 0.
    2. If top_k == 1, returns the indices of the maximum logits (greedy).
    3. If top_k > 0, it extracts the top-k logits, applies temperature, and then applies top_p filtering before sampling via torch.multinomial.
    4. If top_k == 0, it applies temperature and top_p filtering to the full logit set and samples.

    Note: When top_k > 0, the function returns the original vocabulary indices, not the indices relative to the top-k subset.

    # Example: Sample with top-k=50, top-p=0.9, and temperature=0.7
    token_indices = sample(logits, top_k=50, top_p=0.9, temperature=0.7)