Intelligence Artificielle angularforall.com

- Groq : inference LLM ultra-rapide en JavaScript

Groq Llm Inference-Rapide Lpu Llama Mixtral Javascript Node-Js Streaming-Sse Function-Calling Openai-Compatible Ia-Generative Chatbot Agents-Ia
Groq : inference LLM ultra-rapide en JavaScript

Integrez Groq en JavaScript pour une inference LLM ultra-rapide : LPU, modeles Llama et Mixtral, compatibilite SDK OpenAI, streaming, function calling et gestion des rate limits.

Pourquoi Groq est si rapide

Groq ne concoit pas de modeles : il les execute, et il le fait plus vite que quiconque. Le secret tient a son materiel dedie, le LPU (Language Processing Unit), une architecture pensee pour l'inference sequentielle des LLM la ou les GPU sont optimises pour le parallelisme massif de l'entrainement.

Concretement, la ou un GPU classique genere quelques dizaines de tokens par seconde, Groq en produit plusieurs centaines. Pour l'utilisateur, la difference est radicale : une reponse qui s'affichait progressivement apparait quasi instantanement.

L'argument decisif : Groq sert des modeles open source (Llama, Mixtral, Gemma) a une vitesse impossible a obtenir ailleurs. Vous ne payez pas pour un modele proprietaire de pointe, mais pour une rapidite d'inference inegalee.

Prerequis et cle API

Avant de commencer :
  • Compte sur la console Groq et cle API generee
  • Node.js 18+ (support natif de fetch)
  • Cle stockee dans GROQ_API_KEY (variable d'environnement)
# Installer le SDK officiel Groq
npm install groq-sdk

# Stocker la cle (jamais commitee)
echo "GROQ_API_KEY=gsk_..." >> .env

Premier appel chat completions

Le SDK Groq suit le meme modele que les autres : un appel de chat completions avec une liste de messages. Mesurons la vitesse au passage.

// groq-first.js — premier appel et mesure de vitesse
import 'dotenv/config';
import Groq from 'groq-sdk';

const groq = new Groq({ apiKey: process.env.GROQ_API_KEY });

const start = Date.now();

const completion = await groq.chat.completions.create({
  model: 'llama-3.3-70b-versatile',     // modele Llama servi par Groq
  messages: [
    { role: 'system', content: 'Tu es un assistant technique concis.' },
    { role: 'user', content: 'Explique les closures en JavaScript en 3 phrases.' },
  ],
  temperature: 0.5,
  max_tokens: 300,
});

const elapsed = Date.now() - start;
const tokens = completion.usage.completion_tokens;

console.log(completion.choices[0].message.content);
console.log(`\n${tokens} tokens en ${elapsed}ms`);
console.log(`Vitesse : ${Math.round(tokens / (elapsed / 1000))} tokens/s`);
Le champ usage est renvoye comme chez OpenAI : prompt_tokens, completion_tokens et total_tokens. Groq ajoute parfois des metriques de timing detaillees dans la reponse.

Compatibilite SDK OpenAI

Atout majeur pour la migration : l'API Groq est compatible OpenAI. Si votre code utilise deja le SDK OpenAI, il suffit de rediriger la baseURL.

// groq-via-openai.js — reutiliser le SDK OpenAI tel quel
import OpenAI from 'openai';

// Pointer le SDK OpenAI vers l'endpoint Groq
const client = new OpenAI({
  apiKey: process.env.GROQ_API_KEY,
  baseURL: 'https://api.groq.com/openai/v1',   // seule ligne a changer
});

// Le reste du code est identique a un appel OpenAI classique
const res = await client.chat.completions.create({
  model: 'llama-3.3-70b-versatile',
  messages: [{ role: 'user', content: 'Resume le RAG en une phrase.' }],
});

console.log(res.choices[0].message.content);
Strategie multi-provider : grace a cette compatibilite, vous pouvez abstraire le provider derriere une variable d'environnement et basculer entre OpenAI, Groq ou un modele local selon le besoin, sans reecrire votre logique applicative.
// Selecteur de provider via configuration
const providers = {
  openai: { baseURL: undefined, key: process.env.OPENAI_API_KEY, model: 'gpt-4o' },
  groq:   { baseURL: 'https://api.groq.com/openai/v1', key: process.env.GROQ_API_KEY, model: 'llama-3.3-70b-versatile' },
};

function makeClient(name) {
  const p = providers[name];
  return {
    client: new OpenAI({ apiKey: p.key, baseURL: p.baseURL }),
    model: p.model,
  };
}

// Basculer en une ligne : 'groq' pour la vitesse, 'openai' pour le raisonnement
const { client, model } = makeClient(process.env.AI_PROVIDER ?? 'groq');

Streaming token par token

Avec Groq, le streaming devient presque superflu tant la reponse est rapide — mais il reste utile pour les longues generations et l'experience utilisateur.

// groq-stream.js — affichage en streaming
import Groq from 'groq-sdk';
const groq = new Groq({ apiKey: process.env.GROQ_API_KEY });

const stream = await groq.chat.completions.create({
  model: 'llama-3.3-70b-versatile',
  messages: [{ role: 'user', content: 'Ecris un court poeme sur le code.' }],
  stream: true,                  // active le streaming SSE
});

// Chaque chunk contient un fragment de texte
for await (const chunk of stream) {
  const delta = chunk.choices[0]?.delta?.content;
  if (delta) process.stdout.write(delta);
}

Streaming vers un client web (Express)

// Relayer le stream Groq vers le navigateur en SSE
app.get('/chat', async (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');

  const stream = await groq.chat.completions.create({
    model: 'llama-3.3-70b-versatile',
    messages: [{ role: 'user', content: req.query.q }],
    stream: true,
  });

  for await (const chunk of stream) {
    const delta = chunk.choices[0]?.delta?.content ?? '';
    if (delta) res.write(`data: ${JSON.stringify({ delta })}\n\n`);
  }
  res.write('data: [DONE]\n\n');
  res.end();
});

Function calling avec Groq

Les modeles Llama servis par Groq supportent le function calling au format OpenAI, ce qui permet de construire des agents reactifs ultra-rapides.

// groq-tools.js — declarer et gerer un outil
const tools = [{
  type: 'function',
  function: {
    name: 'get_stock_price',
    description: 'Recupere le cours d\'une action',
    parameters: {
      type: 'object',
      properties: { symbol: { type: 'string' } },
      required: ['symbol'],
    },
  },
}];

const res = await groq.chat.completions.create({
  model: 'llama-3.3-70b-versatile',
  messages: [{ role: 'user', content: 'Quel est le cours de AAPL ?' }],
  tools,
  tool_choice: 'auto',
});

const call = res.choices[0].message.tool_calls?.[0];
if (call) {
  const args = JSON.parse(call.function.arguments);
  const price = await getStockPrice(args.symbol);    // votre logique

  // Renvoyer le resultat de l'outil au modele
  const final = await groq.chat.completions.create({
    model: 'llama-3.3-70b-versatile',
    messages: [
      { role: 'user', content: 'Quel est le cours de AAPL ?' },
      res.choices[0].message,
      { role: 'tool', tool_call_id: call.id, content: JSON.stringify(price) },
    ],
  });
  console.log(final.choices[0].message.content);
}
La vitesse de Groq est un atout enorme pour les agents : un agent qui enchaine 5 a 10 appels LLM (planification, appels d'outils, synthese) devient fluide au lieu d'accumuler des secondes d'attente a chaque etape.

Rate limits et gestion des erreurs

Groq applique des limites de debit (requetes et tokens par minute). Un pattern de retry avec backoff exponentiel est indispensable en production.

// retry avec backoff exponentiel sur erreur 429
async function withRetry(fn, maxRetries = 4) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (err) {
      // 429 = rate limit ; on retente avec un delai croissant
      if (err.status === 429 && attempt < maxRetries) {
        const delay = Math.min(1000 * 2 ** attempt, 16000);
        console.warn(`Rate limit, nouvelle tentative dans ${delay}ms`);
        await new Promise((r) => setTimeout(r, delay));
        continue;
      }
      throw err;   // autre erreur ou retries epuises
    }
  }
}

const res = await withRetry(() =>
  groq.chat.completions.create({
    model: 'llama-3.3-70b-versatile',
    messages: [{ role: 'user', content: prompt }],
  })
);
Astuce : les reponses 429 incluent souvent un en-tete indiquant le delai d'attente recommande. Respectez-le plutot que d'utiliser un backoff fixe pour eviter d'aggraver la saturation.

Cas d'usage ou la vitesse change tout

Groq excelle pour :
  • Chatbots et assistants conversationnels reactifs
  • Agents multi-etapes qui enchainent les appels LLM
  • Classification et extraction sur de gros volumes
  • Generation a la volee (suggestions, autocompletion)
  • Pipelines de pre-traitement (resume, traduction batch)
  • Transcription audio rapide via Whisper sur Groq

A l'inverse, pour du raisonnement de pointe (voir notre article sur les modeles de raisonnement) ou de la vision multimodale avancee, les modeles proprietaires conservent souvent l'avantage qualitatif. Une architecture hybride — Groq pour la vitesse, un modele premium pour les taches dures — est souvent le meilleur compromis.

Mesurer la vitesse : latence et debit

« Rapide » ne veut rien dire sans chiffres. Deux metriques comptent cote application : le TTFT (Time To First Token, le delai avant le premier caractere — il conditionne la sensation de reactivite) et le debit en tokens par seconde (qui determine la duree d'affichage d'une reponse longue). Voici comment les mesurer proprement en streaming.

// bench.js — mesurer TTFT et debit reel en streaming
import Groq from 'groq-sdk';
const groq = new Groq({ apiKey: process.env.GROQ_API_KEY });

async function bench(prompt) {
  const t0 = Date.now();
  let firstTokenAt = null;
  let tokens = 0;

  const stream = await groq.chat.completions.create({
    model: 'llama-3.3-70b-versatile',
    messages: [{ role: 'user', content: prompt }],
    stream: true,
  });

  for await (const chunk of stream) {
    const delta = chunk.choices[0]?.delta?.content;
    if (delta) {
      if (firstTokenAt === null) firstTokenAt = Date.now();   // TTFT
      tokens++;
    }
  }

  const total = Date.now() - t0;
  const ttft = firstTokenAt - t0;
  return {
    ttft,                                       // ms avant le 1er token
    debit: Math.round(tokens / ((total - ttft) / 1000)),  // tokens/s
    total,
  };
}

const r = await bench('Explique le DOM virtuel.');
console.log(`TTFT ${r.ttft}ms | ${r.debit} tok/s | total ${r.total}ms`);

A titre indicatif, sur une application interactive, un TTFT inferieur a 200 ms est percu comme instantane. C'est precisement la ou Groq se distingue des fournisseurs GPU classiques. Le tableau ci-dessous resume les ordres de grandeur observes selon le profil de modele (les valeurs exactes evoluent avec les versions).

ProfilTTFT typiqueDebitRessenti utilisateur
Groq (LPU, modele 8B)Tres faibleTres eleveReponse quasi instantanee
Groq (LPU, modele 70B)FaibleEleveStreaming tres fluide
GPU cloud classique 70BMoyenModereAttente perceptible
Modele de raisonnementEleveVariablePlusieurs secondes

Integrer Groq dans une UI web resiliente

Cote front, deux details font la difference : permettre d'annuler une generation en cours (l'utilisateur change d'avis) et basculer sur un fournisseur de secours si Groq sature. On s'appuie sur AbortController et sur la strategie multi-provider vue plus haut.

// chat-client.ts — consommer le flux SSE avec annulation (TypeScript)
export async function streamChat(
  question: string,
  onToken: (t: string) => void,
  signal: AbortSignal,
): Promise<void> {
  const res = await fetch('/chat?q=' + encodeURIComponent(question), { signal });
  if (!res.ok || !res.body) throw new Error('Flux indisponible');

  const reader = res.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { value, done } = await reader.read();
    if (done) break;
    for (const line of decoder.decode(value).split('\n\n')) {
      const data = line.replace(/^data: /, '').trim();
      if (!data || data === '[DONE]') continue;
      onToken(JSON.parse(data).delta);   // append au fur et a mesure
    }
  }
}

// Utilisation : un bouton "Stop" declenche controller.abort()
const controller = new AbortController();
streamChat('Resume cet article', (t) => appendToUI(t), controller.signal);
// server : fallback automatique Groq → OpenAI en cas de saturation
async function chatWithFallback(messages) {
  try {
    return await groq.chat.completions.create({
      model: 'llama-3.3-70b-versatile', messages, stream: true,
    });
  } catch (err) {
    // 429 / 503 cote Groq : on bascule sur un provider de secours
    if ([429, 503].includes(err.status)) {
      console.warn('Groq sature, bascule sur le provider de secours');
      return openai.chat.completions.create({ model: 'gpt-4o-mini', messages, stream: true });
    }
    throw err;
  }
}
UX : grace au TTFT minuscule de Groq, affichez le texte au fil de l'eau plutot que d'attendre la reponse complete. Combine a un bouton d'annulation, l'interface parait instantanee meme sur les reponses longues — un avantage concurrentiel concret pour un chatbot embarque dans votre application.

Couts et choix de modele

Groq facture au token, avec des tarifs generalement competitifs sur les modeles open source. Le choix du modele equilibre vitesse, qualite et cout.

Type de modeleUsage idealCompromis
Llama 70B versatileUsage general, qualite/vitesseEquilibre
Llama 8B instantClassification, extraction massivesTres rapide, moins fin
MixtralContexte long, multilingueBon rapport qualite/prix
GemmaTaches legeresCompact et economique
WhisperTranscription audioSpeech-to-text rapide
Optimiser le cout : reservez les gros modeles (70B) aux taches qui le demandent et routez les taches simples (classification, extraction) vers un modele 8B « instant ». La rapidite de Groq rend ce routage quasi transparent pour l'utilisateur.

Erreurs frequentes a l'integration

L'erreur numero un en passant a Groq depuis OpenAI : oublier de verifier la disponibilite du modele. Le catalogue Groq evolue (les modeles open source apparaissent et disparaissent au fil des versions), et un model code en dur peut renvoyer une 404 du jour au lendemain. Lisez l'identifiant du modele depuis votre configuration et gardez un modele de repli explicite.

Deuxieme piege, contre-intuitif : la latence reseau peut annuler le gain de vitesse du LPU. Si votre serveur appelle Groq depuis une region eloignee, le temps d'aller-retour reseau domine le temps d'inference. Placez votre backend au plus pres, et surtout streamez la reponse vers le navigateur plutot que d'attendre la generation complete cote serveur avant de relayer.

Cote front, beaucoup negligent la gestion de la deconnexion en cours de stream : si l'utilisateur ferme l'onglet ou navigue ailleurs, le flux SSE doit etre coupe proprement (via AbortController) sous peine de continuer a consommer des tokens pour rien. Enfin, ne faites jamais confiance au finish_reason implicitement : verifiez qu'il vaut bien stop et non length, signe que max_tokens a tronque la reponse au milieu d'une phrase.

Dernier point souvent sous-estime : le JSON mode et le function calling sont moins fiables sur les modeles open source que sur les modeles proprietaires de pointe. Un modele 8B « instant » peut renvoyer un JSON legerement malforme ou inventer un argument d'outil. Si votre application depend d'une sortie structuree stricte, validez systematiquement le JSON renvoye (avec Zod ou un schema JSON) et prevoyez un retry ou une escalade vers un modele plus capable en cas d'echec de parsing. La vitesse ne dispense jamais de la validation : un modele rapide qui renvoie une structure invalide une fois sur dix coute plus cher, en bugs et en retries, qu'un modele un peu plus lent mais fiable.

Conclusion

Groq resout un probleme precis et le resout brillamment : la latence de l'inference LLM. En servant des modeles open source sur son materiel LPU, il offre une vitesse qui transforme l'experience des chatbots, des agents et des pipelines de traitement. Sa compatibilite avec le SDK OpenAI rend l'adoption quasi gratuite : une baseURL a changer.

Integrez Groq la ou la reactivite compte, gardez un modele premium pour le raisonnement difficile, et abstrayez le provider derriere une configuration. Avec un retry robuste et un routage par modele, vous obtenez une stack IA a la fois rapide, economique et resiliente.

A retenir :
  • LPU = inference LLM ultra-rapide (centaines de tokens/s)
  • Modeles open source : Llama, Mixtral, Gemma, Whisper
  • Compatible SDK OpenAI : changez juste la baseURL
  • Ideal pour chatbots reactifs et agents multi-etapes
  • Retry avec backoff sur les rate limits 429

Partager