Text Generation
ONNX
Portuguese
llama
onnxruntime
tiny
conversational

TucanoBR/Tucano-160m finetuned for instruction following in portuguese language.

This is a minimal version that does not require the transformers library and weighs only 163mb (quantized file)

from tokenizers import Tokenizer
import onnxruntime as ort
import numpy as np

def generate_chat_response(prompt_input, stopping_text=None, tokenizer_path="tokenizer.json", model_path="model.onnx", *, temperature=0.1, top_k=50, top_p=0.5, repetition_penalty=1.25, max_tokens=4096):
    """
    Args:
        prompt_input (list or str): 
            - If a list, it should be a list of dictionaries representing the chat history.
              Each dictionary should have "role" and "content" keys.
            - If a string, it will be treated as a raw user input and converted internally.
        tokenizer_path (str): Path to the tokenizer JSON file.
        model_path (str): Path to the ONNX model file.

    Returns:
        str: The generated response from the model.
    """
    # Load the tokenizer and ONNX model
    tokenizer = Tokenizer.from_file(tokenizer_path)
    session = ort.InferenceSession(model_path)

    # Handle raw string input by converting it to the expected format
    if isinstance(prompt_input, str):
        messages = [{"role": "user", "content": prompt_input}]
    elif isinstance(prompt_input, list):
        messages = prompt_input
    else:
        raise ValueError("prompt_input must be either a string or a list of dictionaries.")

    # Construct the input text based on the chat schema
    input_text_parts = []
    for message in messages:
        role = message["role"]
        content = message["content"]
        if role == "user":
            input_text_parts.append(f"<instruction>{content}</instruction>")
        elif role == "assistant":
            input_text_parts.append(content)
    input_text = "".join(input_text_parts)

    # Tokenize the input text
    encoded_input = tokenizer.encode(input_text)
    input_ids = np.array([encoded_input.ids], dtype=np.int64)  # Shape: (1, sequence_length)

    # Prepare attention mask and position IDs
    attention_mask = np.ones_like(input_ids, dtype=np.int64)  # Shape: (1, sequence_length)
    position_ids = np.arange(input_ids.shape[1], dtype=np.int64).reshape(1, -1)  # Shape: (1, sequence_length)

    # Prepare past_key_values (initialize as empty tensors)
    num_layers = 12  # Adjust based on your model's number of layers
    num_heads = 12   # Adjust based on your model's number of attention heads
    head_dim = 64    # Adjust based on your model's head dimensionality
    batch_size = 1  
    past_sequence_length = 0  # Initially, no past context exists

    past_key_values = []
    for _ in range(num_layers):
        key = np.zeros((batch_size, num_heads, past_sequence_length, head_dim), dtype=np.float32)
        value = np.zeros((batch_size, num_heads, past_sequence_length, head_dim), dtype=np.float32)
        past_key_values.append(key)
        past_key_values.append(value)

    eos_token_id = 2

    def sample_next_token(logits, generated_ids, temperature=1.0, top_k=0, top_p=1.0, repetition_penalty=1.0):
        logits = logits.copy()
        for token_id in set(generated_ids):
            if logits[token_id] < 0:
                logits[token_id] *= repetition_penalty
            else:
                logits[token_id] /= repetition_penalty

        logits = logits / temperature
        exp_logits = np.exp(logits - np.max(logits))
        probs = exp_logits / exp_logits.sum()

        if top_k > 0:
            indices_to_remove = probs < np.sort(probs)[-top_k]
            probs[indices_to_remove] = 0
            probs = probs / probs.sum()

        if top_p < 1.0:
            sorted_indices = np.argsort(probs)[::-1]
            sorted_probs = probs[sorted_indices]
            cumulative_probs = np.cumsum(sorted_probs)
            cutoff_index = np.searchsorted(cumulative_probs, top_p)
            probs[sorted_indices[cutoff_index+1:]] = 0
            probs = probs / probs.sum()

        next_token_id = np.random.choice(len(probs), p=probs)
        return next_token_id

    # Autoregressive generation loop
    generated_token_ids = []
    for _ in range(max_tokens):
        input_feed = {
            "input_ids": input_ids,
            "attention_mask": attention_mask,
            "position_ids": position_ids,
        }

        for i in range(num_layers):
            input_feed[f"past_key_values.{i}.key"] = past_key_values[2 * i]
            input_feed[f"past_key_values.{i}.value"] = past_key_values[2 * i + 1]

        outputs = session.run(None, input_feed)
        logits = outputs[0]  # Shape: (1, sequence_length, vocab_size)
        updated_past_key_values = outputs[1:]

        last_logits = logits[0, -1, :]
        next_token_id = sample_next_token(
            last_logits,
            generated_token_ids,
            temperature=temperature,
            top_k=top_k,
            top_p=top_p,
            repetition_penalty=repetition_penalty
        )

        generated_token_ids.append(next_token_id)

        if next_token_id == eos_token_id:
            break

        if stopping_text:
            decoded_text = tokenizer.decode(generated_token_ids)
            if stopping_text in decoded_text:
                break
    
        input_ids = np.array([[next_token_id]], dtype=np.int64)
        attention_mask = np.ones_like(input_ids, dtype=np.int64)
        position_ids = np.array([[len(encoded_input.ids) + len(generated_token_ids)]], dtype=np.int64)
        past_key_values = updated_past_key_values

    # Decode the generated token IDs into text
    generated_text = tokenizer.decode(generated_token_ids)

    # Remove the stop sequence from the generated text
    if stopping_text:
        generated_text = generated_text.split(stopping_text)[0]

    return generated_text

# Example usage
if __name__ == "__main__":
    # Using raw string input
    raw_input = "Era uma vez"
    response = generate_chat_response(raw_input, max_tokens=50)
    response
    # Era uma vez um jovem chamado Jack que vivia em uma pequena cidade chamada Little Rock. Ele era conhecido por ser muito inteligente e tinha um senso de humor peculiar.
    # Jack sempre foi fascinado pela cultura pop, mas nunca imaginou que seria tão interessante para

    # Using list of dictionaries input
    dict_input = [
        {"role": "user", "content": "Quais são as melhores práticas para programação em Python?"}
    ]
    response = generate_chat_response(dict_input)
    response
    # 1. Use uma variedade de bibliotecas e estruturas: Python é um sistema amplamente utilizado para programação em vários idiomas. Ele permite que você crie aplicativos complexos com facilidade, sem a necessidade de escrever código complexo.

    # 2. Minimize o tamanho da pilha: O uso excessivo do espaço na memória pode levar ao desempenho lento. Portanto, minimize o tamanho da sua pilha usando funções como min-stack ou splunk.

    # 3. Implementar tratamento de erros: A implementação adequada dos testes unitários garante que seu aplicativo funcione conforme esperado.

    # 4. Teste seus aplicativos minuciosamente: teste exaustivamente os recursos do seu aplicativo, incluindo as funcionalidades desejadas, antes de implementá-los.

    # 5. Mantenha-se atualizado sobre novas tecnologias: As atualizações mais recentes podem melhorar significativamente suas capacidades de desenvolvimento.

    # 6. Monitore regularmente seu código: monitore continuamente seu código, verificando se há bugs e fazendo alterações.

    # 7. Utilize ferramentas de gerenciamento de projetos: Ferramentas de gerenciamento de projetos, como Trello, Asana e Jira, permitem gerenciar tarefas e prazos de maneira eficiente.

    # 8. Colabore com outros desenvolvedores: Trabalhe com outras equipes e parceiros para colaborar no projeto.

    # 9. Estabelecer relacionamentos sólidos entre diferentes linguagens de programação: Construir relacionamentos fortes entre diferentes linguagens de programação, garantindo compatibilidade e flexibilidade.

    # 10. Considere usar frameworks de terceiros: Frameworks, como Python, Ruby on Rails e Node.js, fornecem APIs robustas para construir aplicações web complexas.

    # Concluindo, a programação em Python requer atenção aos detalhes, mas também envolve muito trabalho duro e dedicação. Seguindo essas práticas recomendadas e utilizando técnicas adequadas de desenvolvimento, você poderá criar aplicativos poderosos e eficientes que atendam às necessidades específicas das empresas.
Downloads last month
2
Inference Providers NEW
This model is not currently available via any of the supported Inference Providers.
The model cannot be deployed to the HF Inference API: The HF Inference API does not support text-generation models for onnx library.

Model tree for cnmoro/Tucano-160m-Portuguese-Instruct-ONNX

Quantized
(1)
this model

Datasets used to train cnmoro/Tucano-160m-Portuguese-Instruct-ONNX