Context length
Thanks for this awesome model.
It works fine with vLLM - I am running it with two A100s at about 33 tokens per second.
The only downside is that when reaching 32k tokens, the model starts outputting random tokens, while it should be fine up to 128k tokens.
Do you have any idea why this behavior occurs?
Do you have an example which reproduces this behavior so we can replicate it on our end as well?
Here how I run vllm :
vllm serve neuralmagic/Meta-Llama-3.1-70B-Instruct-quantized.w4a16 --tensor-parallel-size 2 --max-model-len 131072
Here is my test program :
$ cat test_assistant.py
import requests, time
import json, os, sys
from typing import List, Dict
class ChatClient:
def __init__(self, base_url: str, token: str, model: str):
"""
Initialise le client de chat.
Args:
base_url: URL du service (ex: 'http://localhost:8000')
token: Token d'authentification
model: Nom du modèle à utiliser
"""
self.base_url = base_url.rstrip('/')
self.headers = {
'accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}'
}
self.model = model
self.messages = [
{
"content": "You are a helpful assistant",
"role": "system"
}
]
self.total_tokens = 0
self.context_len = 24*1024 - 80
# Statistiques de performance
self.total_time = 0
self.total_completion_tokens = 0
def add_message(self, content: str, role: str = "user") -> None:
"""Ajoute un message à l'historique."""
self.messages.append({
"content": content,
"role": role
})
def call_api(self) -> Dict:
"""Fait l'appel à l'API et retourne la réponse."""
max_tokens = self.context_len - self.total_tokens
print("Je peux encore produire : ", max_tokens, " tokens")
payload = {
"messages": self.messages,
"model": self.model,
"max_tokens": max_tokens,
"n": 1,
"stream": False,
"temperature": 0.9,
"priority": 0
}
start_time = time.time()
response = requests.post(
f'{self.base_url}/v1/chat/completions',
headers=self.headers,
json=payload
)
elapsed_time = time.time() - start_time
if response.status_code != 200:
raise Exception(f"Erreur API: {response.status_code} - {response.text}")
response_data = response.json()
# Mettre à jour les statistiques de performance
completion_tokens = response_data.get('usage', {}).get('completion_tokens', 0)
self.total_time += elapsed_time
self.total_completion_tokens += completion_tokens
# Ajouter les informations de performance à la réponse
response_data['performance'] = {
'elapsed_time': elapsed_time,
'tokens_per_second': completion_tokens / elapsed_time if elapsed_time > 0 else 0,
'average_tokens_per_second': self.total_completion_tokens / self.total_time if self.total_time > 0 else 0
}
return response_data
def display_token_info(self, response: Dict) -> None:
"""Affiche les informations sur l'utilisation des tokens."""
usage = response.get('usage', {})
performance = response.get('performance', {})
prompt_tokens = usage.get('prompt_tokens', 0)
completion_tokens = usage.get('completion_tokens', 0)
total_tokens = usage.get('total_tokens', 0)
self.total_tokens += total_tokens
print("\n--- Utilisation des tokens pour cet échange ---")
print(f"Tokens prompt: {prompt_tokens}")
print(f"Tokens réponse: {completion_tokens}")
print(f"Total pour cet échange: {total_tokens}")
print(f"Total cumulé de la conversation: {self.total_tokens}")
print("\n--- Performance ---")
print(f"Temps de génération: {performance.get('elapsed_time', 0):.2f} secondes")
print(f"Débit instantané: {performance.get('tokens_per_second', 0):.2f} tokens/seconde")
print(f"Débit moyen: {performance.get('average_tokens_per_second', 0):.2f} tokens/seconde")
print("-------------------------------------------")
def process_input(self, user_input: str) -> bool:
"""
Traite une entrée utilisateur et retourne False si on doit quitter.
Args:
user_input: L'entrée utilisateur à traiter
Returns:
bool: False si on doit quitter, True sinon
"""
if user_input.lower() == 'quit':
print("Au revoir!")
return False
# Ajouter le message utilisateur et faire l'appel
self.add_message(user_input)
try:
response = self.call_api()
# Extraire et afficher la réponse
assistant_message = response['choices'][0]['message']['content']
print(f"\nAssistant: {assistant_message}")
# Ajouter la réponse à l'historique
self.add_message(assistant_message, "assistant")
# Afficher les informations sur les tokens
self.display_token_info(response)
except Exception as e:
print(f"\nErreur: {str(e)}")
return True
def chat_loop(self, input_file: str = None):
"""
Démarre une boucle de chat interactive ou lit depuis un fichier.
Args:
input_file: Chemin vers le fichier d'entrée (optionnel)
"""
if input_file:
try:
with open(input_file, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line: # Ignorer les lignes vides
print(f"\nVous: {line}")
if not self.process_input(line):
break
except FileNotFoundError:
print(f"Erreur: Le fichier '{input_file}' n'existe pas.")
return
except Exception as e:
print(f"Erreur lors de la lecture du fichier: {str(e)}")
return
else:
print("Bienvenue! Tapez 'quit' pour quitter.")
while True:
user_input = input("\nVous: ").strip()
if not self.process_input(user_input):
break
def main():
# Obtenir les variables d'environnement ou utiliser des valeurs par défaut
base_url = os.getenv('MY_IP_PORT', 'http://localhost:8000')
if not base_url.startswith('http'):
base_url = f'http://{base_url}'
token = os.getenv('MY_TOKEN', 'mytoken')
model = os.getenv('MY_MODEL', 'neuralmagic/Llama-3.1-Nemotron-70B-Instruct-HF-FP8-dynamic')
# Vérifier si un fichier est fourni en argument
input_file = sys.argv[1] if len(sys.argv) > 1 else None
# Créer et démarrer le client
client = ChatClient(base_url, token, model)
client.chat_loop(input_file)
if __name__ == "__main__":
main()
``
here how I run my test program :
$ python test_assistant.py interactions.txt
here the content of the file interactions.txt require to automate testing (each line will count as was input from the user)
$ cat interactions.txt
Créer un jeu de sudoku en python avec un IHM. N'oublie de permettre à l'utilisateur de générer de nouvelle grille, la fonction de résolution automatique, et les fonctions permettant à l'utilisateur de placer et retirer ces propres chiffres.
Ajoute une base de donnée pour stocker les parties, les temps de résolutions par utilisateur, la difficulté. Puis ajoute des fonctions de visualisation de statistique à partir de la base de données avec des projections sur les performances futures.
Ajoute une boite de contrôle qui permet à l'utilisateur de changer les couleurs du jeu. Notamment les couleurs utilisé pour marqué les nombres mal placé ou bien placé, la couleurs de visualisation graphiques. Ajoute aussi une fonction pour sauvegarder et reprendre le jeu.
Ajoute 20 grilles par défaut dans la base de données. 5 très faciles, 5 faciles, 5 moyennes, et 5 difficiles.
Ajoute un déploiement Heroku et une intégration Facebook.
Écris la notice utilisateur en html, pour Français et Anglais.
Sur le même modèle que le jeu de sudoku, ajoute un jeu de pendu, avec les même fonctions, intégration, stockage et système de prévision.
Pour plus de performances converti les programmes python en rust.
Just to clarify: the example code snippet you shared uses the neuralmagic/Meta-Llama-3.1-70B-Instruct-quantized.w4a16
model, while the issue you mentioned is opened at the neuralmagic/Llama-3.1-Nemotron-70B-Instruct-HF-FP8-dynamic
model. Could you please clarify which model is causing problems for you with the 32k context inputs?
Forgive me, vllm use "neuralmagic/Llama-3.1-Nemotron-70B-Instruct-HF-FP8-dynamic" like in the test script. I miss copy the wrong test from another test set.
run command is :
vllm serve neuralmagic/Llama-3.1-Nemotron-70B-Instruct-HF-FP8-dynamic --tensor-parallel-size 2 --max-model-len 131072
even if you have down a really good job on Meta-Llama-3.1-70B-Instruct-quantized.w4a16 too.
The hype is on Nemoton.