Formation IA Générative Open Source
Les Vision-Language Models combinent la compréhension du texte et des images pour accomplir des tâches complexes comme la description d'images, le VQA (Visual Question Answering), et le raisonnement visuel.
CLIP d'OpenAI est le fondement de nombreux VLM modernes. Il apprend à associer images et textes dans un espace latent commun.
LLaVA connecte CLIP à un LLM (Vicuna/Llama) via un projecteur linéaire simple.
Famille VL de Qwen avec support multi-images et haute résolution.
VLM haute performance avec architecture innovante.
VLM avec grounding visuel et compréhension spatiale.
# Installation
pip install transformers pillow torch accelerate
# Script d'inférence LLaVA
from transformers import LlavaNextProcessor, LlavaNextForConditionalGeneration
from PIL import Image
import torch
class VLMInference:
def __init__(self, model_name="llava-hf/llava-v1.6-mistral-7b-hf"):
"""Initialise le modèle VLM"""
self.device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"🚀 Chargement de {model_name}...")
self.processor = LlavaNextProcessor.from_pretrained(model_name)
self.model = LlavaNextForConditionalGeneration.from_pretrained(
model_name,
torch_dtype=torch.float16 if self.device == "cuda" else torch.float32,
device_map="auto"
)
def query_image(self, image_path, prompt):
"""
Pose une question sur une image
Args:
image_path: Chemin vers l'image
prompt: Question ou instruction
Returns:
Réponse du modèle
"""
# Charger l'image
image = Image.open(image_path).convert("RGB")
# Format LLaVA conversation
conversation = [
{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "image"}
]
}
]
# Préparation des inputs
text_prompt = self.processor.apply_chat_template(
conversation, add_generation_prompt=True
)
inputs = self.processor(
text=text_prompt,
images=image,
return_tensors="pt"
).to(self.device)
# Génération
with torch.no_grad():
output = self.model.generate(
**inputs,
max_new_tokens=512,
do_sample=False
)
# Décodage
response = self.processor.decode(
output[0],
skip_special_tokens=True
)
# Extraire la réponse (après ASSISTANT:)
if "ASSISTANT:" in response:
response = response.split("ASSISTANT:")[-1].strip()
return response
# Utilisation
vlm = VLMInference()
# Exemple 1: Description d'image
description = vlm.query_image(
"photo.jpg",
"Décris cette image en détail."
)
print("📝 Description:", description)
# Exemple 2: Visual Question Answering
answer = vlm.query_image(
"chart.png",
"Combien de personnes sont présentes dans l'image?"
)
print("❓ Réponse:", answer)
# Exemple 3: OCR et extraction d'info
text = vlm.query_image(
"document.jpg",
"Extrais tout le texte visible dans ce document."
)
print("📄 Texte extrait:", text)
# Exemple 4: Raisonnement visuel
reasoning = vlm.query_image(
"scene.jpg",
"Que se passe-t-il dans cette scène? Explique le contexte."
)
print("🧠 Analyse:", reasoning)
| Cas d'Usage | Description | Modèle Recommandé |
|---|---|---|
| Image Captioning | Génération de descriptions d'images | LLaVA-1.6, InternVL |
| VQA | Répondre à des questions sur des images | Qwen2-VL, CogVLM2 |
| OCR Intelligent | Extraction et compréhension de texte | Qwen2-VL, CogVLM |
| Visual Grounding | Localiser des objets dans une image | CogVLM2, Qwen-VL |
| GUI Understanding | Comprendre des interfaces utilisateur | CogVLM, InternVL |
| Document Analysis | Analyser des documents complexes | Qwen2-VL, InternVL |
# Fine-tuning LLaVA avec LoRA
from transformers import TrainingArguments, Trainer
from peft import LoraConfig, get_peft_model
# Configuration LoRA (uniquement sur le projecteur et LLM)
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
lora_dropout=0.05,
bias="none"
)
# Appliquer LoRA
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# Sortie: trainable params: 8.4M || all params: 7.2B || trainable%: 0.12%
# Dataset personnalisé (format: image + question + answer)
from torch.utils.data import Dataset
class VLMDataset(Dataset):
def __init__(self, data, processor):
self.data = data # Liste de dicts: {"image": path, "question": str, "answer": str}
self.processor = processor
def __len__(self):
return len(self.data)
def __getitem__(self, idx):
item = self.data[idx]
image = Image.open(item["image"]).convert("RGB")
conversation = [
{
"role": "user",
"content": [
{"type": "text", "text": item["question"]},
{"type": "image"}
]
},
{
"role": "assistant",
"content": [{"type": "text", "text": item["answer"]}]
}
]
text = self.processor.apply_chat_template(conversation)
inputs = self.processor(text=text, images=image, return_tensors="pt")
return inputs
# Training
training_args = TrainingArguments(
output_dir="./llava-finetuned",
num_train_epochs=3,
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=2e-4,
fp16=True,
save_steps=500,
logging_steps=100
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset
)
trainer.train()
Les modèles de diffusion (Stable Diffusion, FLUX.1, etc.) génèrent des images en apprenant à inverser un processus de bruit progressif.
Text Prompt
│
├─→ CLIP ViT-L/14 ────┐
│ ├─→ Text Embeddings (Concat)
└─→ OpenCLIP ViT-G ───┘ │
▼
Latent (Random Noise) ─→ U-Net (2.6B params)
z₀ │ Time embedding
│ Conditioning
▼
Denoised Latent z_t
│
▼
VAE Decoder
│
▼
Image 1024x1024
Nouveau 2024 Créé par les fondateurs originaux de Stable Diffusion. Architecture transformer-based révolutionnaire.
| Modèle | Params | Licence | Qualité |
|---|---|---|---|
| FLUX.1 [pro] | 12B | API uniquement | SOTA (meilleur qualité) |
| FLUX.1 [dev] | 12B | Non-commercial | Excellent (distillé de pro) |
| FLUX.1 [schnell] | 12B | Apache 2.0 (Open) | Très bon (4 steps) |
# Installation
pip install diffusers transformers accelerate safetensors
# 1. Stable Diffusion XL
from diffusers import DiffusionPipeline
import torch
class ImageGenerator:
def __init__(self, model="stabilityai/stable-diffusion-xl-base-1.0"):
"""Initialise le pipeline de génération"""
self.device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"🎨 Chargement de {model}...")
self.pipe = DiffusionPipeline.from_pretrained(
model,
torch_dtype=torch.float16 if self.device == "cuda" else torch.float32,
use_safetensors=True
)
self.pipe.to(self.device)
# Optimisation (optionnel)
if self.device == "cuda":
self.pipe.enable_xformers_memory_efficient_attention()
def generate(
self,
prompt,
negative_prompt="",
num_images=1,
steps=30,
guidance_scale=7.5,
width=1024,
height=1024,
seed=None
):
"""
Génère des images à partir d'un prompt
Args:
prompt: Description de l'image souhaitée
negative_prompt: Ce qu'on ne veut PAS voir
num_images: Nombre d'images à générer
steps: Nombre de steps de denoising (↑ = meilleur qualité)
guidance_scale: Force du prompt (7-12 optimal)
width/height: Dimensions (multiples de 64)
seed: Seed pour reproductibilité
Returns:
Liste d'images PIL
"""
generator = torch.Generator(self.device)
if seed is not None:
generator.manual_seed(seed)
images = self.pipe(
prompt=prompt,
negative_prompt=negative_prompt,
num_images_per_prompt=num_images,
num_inference_steps=steps,
guidance_scale=guidance_scale,
width=width,
height=height,
generator=generator
).images
return images
# Utilisation SDXL
gen = ImageGenerator()
# Exemple 1: Génération simple
images = gen.generate(
prompt="A majestic lion standing on a cliff at sunset, photorealistic, 8k, highly detailed",
negative_prompt="cartoon, anime, low quality, blurry",
num_images=4,
seed=42
)
for i, img in enumerate(images):
img.save(f"lion_{i}.png")
# Exemple 2: Style artistique
images = gen.generate(
prompt="Portrait of a cyborg woman, cyberpunk style, neon lights, digital art by artgerm",
steps=50,
guidance_scale=9.0
)
# 2. FLUX.1 schnell (ultra-rapide)
from diffusers import FluxPipeline
flux = FluxPipeline.from_pretrained(
"black-forest-labs/FLUX.1-schnell",
torch_dtype=torch.bfloat16
).to("cuda")
# Génération en 4 steps seulement!
image = flux(
prompt="A cat holding a sign that says 'FLUX is amazing'",
num_inference_steps=4, # Très rapide
guidance_scale=0.0 # FLUX schnell n'utilise pas de CFG
).images[0]
image.save("flux_cat.png")
Contrôle la force du prompt. Formula: output = unconditional + scale * (conditional - unconditional)
# Changer le sampler
from diffusers import EulerAncestralDiscreteScheduler
pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(
pipe.scheduler.config
)
# Samplers populaires:
# - DPM++ 2M Karras (qualité, 20-25 steps)
# - Euler A (rapide, 15-20 steps)
# - DDIM (déterministe)
# - UniPC (très rapide, 5-10 steps)
Contrôle spatial précis (pose, edges, depth, etc.)
from diffusers import StableDiffusionXLControlNetPipeline, ControlNetModel
from controlnet_aux import OpenposeDetector
from PIL import Image
# Charger ControlNet Pose
controlnet = ControlNetModel.from_pretrained(
"thibaud/controlnet-openpose-sdxl-1.0",
torch_dtype=torch.float16
)
pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
controlnet=controlnet,
torch_dtype=torch.float16
).to("cuda")
# Extraire la pose d'une image de référence
openpose = OpenposeDetector.from_pretrained("lllyasviel/ControlNet")
reference_image = Image.open("person.jpg")
pose_image = openpose(reference_image)
# Générer avec contrôle de pose
image = pipe(
prompt="A superhero in a dynamic pose, comic book style",
image=pose_image,
controlnet_conditioning_scale=0.8
).images[0]
# ControlNet types disponibles:
# - openpose (pose humaine)
# - canny (contours)
# - depth (profondeur)
# - scribble (croquis)
# - mlsd (lignes architecturales)
Fine-tuning léger pour styles, personnages, concepts spécifiques.
# Charger un LoRA depuis CivitAI ou HuggingFace
pipe.load_lora_weights("path/to/lora.safetensors")
# Ajuster l'intensité du LoRA
pipe.set_adapters(["lora_name"], adapter_weights=[0.8])
# Exemple: Générer dans un style spécifique
image = pipe(
prompt="a cute robot, ",
cross_attention_kwargs={"scale": 0.8}
).images[0]
# Training LoRA (dataset: 10-50 images d'un concept)
# Voir Kohya's SD scripts ou SimpleTuner
[Sujet principal], [Style], [Détails], [Lighting], [Qualité]
| Composante | Exemples |
|---|---|
| Sujet | portrait, landscape, product, character, scene |
| Style | photorealistic, anime, oil painting, digital art, concept art |
| Lighting | golden hour, studio lighting, dramatic shadows, soft light |
| Qualité | 8k, highly detailed, masterpiece, trending on artstation |
| Negative | blurry, low quality, deformed, watermark, text |
Whisper d'OpenAI est le modèle STT open source de référence, supportant 100+ langues avec une précision impressionnante.
| Modèle | Params | WER (EN) | Vitesse | Usage |
|---|---|---|---|---|
| tiny | 39M | ~10% | Très rapide | Démo, temps réel |
| base | 74M | ~7% | Rapide | Usage général rapide |
| small | 244M | ~5% | Moyen | Bon compromis |
| medium | 769M | ~4% | Lent | Haute précision |
| large-v3 | 1.55B | ~3% | Très lent | Production, meilleure qualité |
# Installation
pip install transformers torch accelerate ffmpeg-python
from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor, pipeline
import torch
class WhisperSTT:
def __init__(self, model_size="large-v3", device=None):
"""
Initialise Whisper
Args:
model_size: tiny/base/small/medium/large-v3
device: cuda/cpu (auto-détecté si None)
"""
self.device = device or ("cuda" if torch.cuda.is_available() else "cpu")
model_id = f"openai/whisper-{model_size}"
print(f"🎙️ Chargement de Whisper {model_size}...")
self.model = AutoModelForSpeechSeq2Seq.from_pretrained(
model_id,
torch_dtype=torch.float16 if self.device == "cuda" else torch.float32,
low_cpu_mem_usage=True,
use_safetensors=True
).to(self.device)
self.processor = AutoProcessor.from_pretrained(model_id)
self.pipe = pipeline(
"automatic-speech-recognition",
model=self.model,
tokenizer=self.processor.tokenizer,
feature_extractor=self.processor.feature_extractor,
max_new_tokens=128,
chunk_length_s=30,
batch_size=16,
torch_dtype=torch.float16 if self.device == "cuda" else torch.float32,
device=self.device,
)
def transcribe(
self,
audio_path,
language=None,
task="transcribe",
return_timestamps=False
):
"""
Transcrit un fichier audio
Args:
audio_path: Chemin vers audio (mp3, wav, m4a, etc.)
language: Code langue (fr, en, es, etc.) ou None pour auto-detect
task: "transcribe" (langue originale) ou "translate" (→ anglais)
return_timestamps: Renvoyer les timestamps par segment
Returns:
Transcription texte ou dict avec timestamps
"""
generate_kwargs = {"task": task}
if language:
generate_kwargs["language"] = language
result = self.pipe(
audio_path,
generate_kwargs=generate_kwargs,
return_timestamps=return_timestamps
)
return result
# Utilisation
stt = WhisperSTT(model_size="medium")
# Exemple 1: Transcription simple (auto-detect langue)
result = stt.transcribe("podcast.mp3")
print("📝 Transcription:", result["text"])
# Exemple 2: Avec timestamps (pour sous-titres)
result = stt.transcribe(
"interview.wav",
language="fr",
return_timestamps=True
)
for chunk in result["chunks"]:
start, end = chunk["timestamp"]
text = chunk["text"]
print(f"[{start:.2f}s - {end:.2f}s] {text}")
# Exemple 3: Traduction vers anglais
result = stt.transcribe(
"french_audio.mp3",
task="translate" # Traduit vers anglais
)
print("🌐 Traduction EN:", result["text"])
# Exemple 4: Batch processing
import os
from pathlib import Path
def transcribe_directory(audio_dir, output_dir):
"""Transcrit tous les audios d'un dossier"""
Path(output_dir).mkdir(exist_ok=True)
for audio_file in Path(audio_dir).glob("*.mp3"):
result = stt.transcribe(str(audio_file), language="fr")
output_file = Path(output_dir) / f"{audio_file.stem}.txt"
output_file.write_text(result["text"], encoding="utf-8")
print(f"✓ {audio_file.name} → {output_file.name}")
transcribe_directory("./podcasts", "./transcriptions")
TTS multilingue avec support émotions, musique, effets sonores.
pip install git+https://github.com/suno-ai/bark.git
from bark import SAMPLE_RATE, generate_audio, preload_models
from scipy.io.wavfile import write as write_wav
# Télécharger les modèles
preload_models()
# Générer audio avec émotions
text = """
[laughs] Bonjour! Je suis Bark, un modèle TTS open source.
Je peux parler dans différentes langues et avec des émotions!
"""
audio_array = generate_audio(text, history_prompt="v2/fr_speaker_6")
write_wav("bark_output.wav", SAMPLE_RATE, audio_array)
# Effets spéciaux
text_fx = "[clears throat] ♪ I can even sing! ♪ [laughs]"
audio = generate_audio(text_fx)
TTS avec voice cloning (cloner une voix à partir de 6s d'audio).
pip install TTS
from TTS.api import TTS
# Initialiser XTTS
tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to("cuda")
# Méthode 1: Voix pré-entraînée
tts.tts_to_file(
text="Bonjour, ceci est un test de synthèse vocale.",
speaker="Claribel Dervla", # Voix disponible
language="fr",
file_path="output.wav"
)
# Méthode 2: Voice cloning
tts.tts_to_file(
text="Je clone cette voix avec seulement 6 secondes d'audio de référence!",
speaker_wav="reference_voice.wav", # 6s minimum
language="fr",
file_path="cloned_voice.wav"
)
# Liste des voix disponibles
print(tts.speakers)
Contrôle fin de la voix (genre, pitch, vitesse, qualité audio).
pip install git+https://github.com/huggingface/parler-tts.git
from parler_tts import ParlerTTSForConditionalGeneration
from transformers import AutoTokenizer
import soundfile as sf
import torch
# Charger modèle
model = ParlerTTSForConditionalGeneration.from_pretrained(
"parler-tts/parler-tts-large-v1"
).to("cuda")
tokenizer = AutoTokenizer.from_pretrained("parler-tts/parler-tts-large-v1")
# Description détaillée de la voix souhaitée
description = """
A female speaker with a slightly high-pitched voice delivers her words
quite expressively, in a very confined sounding environment with clear audio quality.
"""
prompt = "Bonjour, comment puis-je vous aider aujourd'hui?"
input_ids = tokenizer(description, return_tensors="pt").input_ids.to("cuda")
prompt_input_ids = tokenizer(prompt, return_tensors="pt").input_ids.to("cuda")
generation = model.generate(input_ids=input_ids, prompt_input_ids=prompt_input_ids)
audio_arr = generation.cpu().numpy().squeeze()
sf.write("parler_output.wav", audio_arr, model.config.sampling_rate)
class VoiceAssistant:
"""Assistant vocal complet STT → Process → TTS"""
def __init__(self):
# STT
self.stt = WhisperSTT(model_size="base")
# TTS
self.tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2").to("cuda")
# LLM (optionnel, pour répondre aux questions)
from transformers import pipeline
self.llm = pipeline("text-generation", model="meta-llama/Llama-3.1-8B-Instruct")
def process_audio_query(self, audio_path, reference_voice=None):
"""
Pipeline complet: Audio question → Texte → LLM → Audio réponse
Args:
audio_path: Question audio
reference_voice: Voix pour la réponse (optionnel)
Returns:
Chemin vers réponse audio
"""
# 1. STT: Audio → Texte
print("🎙️ Transcription...")
transcription = self.stt.transcribe(audio_path, language="fr")
user_query = transcription["text"]
print(f"❓ Question: {user_query}")
# 2. LLM: Générer réponse
print("🤖 Génération réponse...")
messages = [
{"role": "system", "content": "Tu es un assistant utile et concis."},
{"role": "user", "content": user_query}
]
response = self.llm(
messages,
max_new_tokens=200,
do_sample=True,
temperature=0.7
)
answer = response[0]["generated_text"][-1]["content"]
print(f"💬 Réponse: {answer}")
# 3. TTS: Texte → Audio
print("🔊 Synthèse vocale...")
output_path = "assistant_response.wav"
if reference_voice:
self.tts.tts_to_file(
text=answer,
speaker_wav=reference_voice,
language="fr",
file_path=output_path
)
else:
self.tts.tts_to_file(
text=answer,
speaker="Claribel Dervla",
language="fr",
file_path=output_path
)
print(f"✓ Audio généré: {output_path}")
return output_path
# Utilisation
assistant = VoiceAssistant()
response_audio = assistant.process_audio_query("question.wav")
La génération vidéo par IA étend les modèles de diffusion d'images au domaine temporel, en maintenant la cohérence entre les frames.
2024 Modèle open source de génération vidéo text-to-video de haute qualité.
| Modèle | Params | Résolution | Durée | VRAM |
|---|---|---|---|---|
| CogVideoX-2B | 2B | 720x480 | 6s @ 8fps | ~18GB |
| CogVideoX-5B | 5B | 720x480 | 6s @ 8fps | ~30GB |
| CogVideoX-5B-I2V | 5B | 720x480 | 6s @ 8fps | ~30GB (image→video) |
# Installation
pip install diffusers transformers accelerate imageio[ffmpeg]
import torch
from diffusers import CogVideoXPipeline
from diffusers.utils import export_to_video
class VideoGenerator:
def __init__(self, model="THUDM/CogVideoX-2b"):
"""
Initialise le générateur vidéo
Args:
model: THUDM/CogVideoX-2b ou THUDM/CogVideoX-5b
"""
self.device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"🎬 Chargement de {model}...")
self.pipe = CogVideoXPipeline.from_pretrained(
model,
torch_dtype=torch.float16
).to(self.device)
# Optimisations mémoire
self.pipe.enable_model_cpu_offload()
self.pipe.enable_sequential_cpu_offload()
self.pipe.vae.enable_slicing()
self.pipe.vae.enable_tiling()
def generate_video(
self,
prompt,
num_frames=49,
num_inference_steps=50,
guidance_scale=6.0,
seed=None
):
"""
Génère une vidéo à partir d'un prompt
Args:
prompt: Description de la vidéo
num_frames: Nombre de frames (49 = ~6s @ 8fps)
num_inference_steps: Steps de diffusion
guidance_scale: Force du prompt
seed: Seed pour reproductibilité
Returns:
Tensor vidéo [frames, height, width, channels]
"""
generator = torch.Generator(device=self.device)
if seed is not None:
generator.manual_seed(seed)
video = self.pipe(
prompt=prompt,
num_frames=num_frames,
num_inference_steps=num_inference_steps,
guidance_scale=guidance_scale,
generator=generator
).frames[0]
return video
# Utilisation
gen = VideoGenerator(model="THUDM/CogVideoX-2b")
# Exemple 1: Génération simple
video = gen.generate_video(
prompt="A panda eating bamboo in a bamboo forest, natural lighting, high quality",
seed=42
)
# Sauvegarder en MP4
export_to_video(video, "panda.mp4", fps=8)
# Exemple 2: Mouvement de caméra
video = gen.generate_video(
prompt="""
Cinematic shot of a futuristic city at night,
camera slowly panning from left to right,
neon lights reflecting on wet streets,
cyberpunk aesthetic, 8k quality
""",
num_inference_steps=60,
guidance_scale=7.0
)
export_to_video(video, "cyberpunk_city.mp4", fps=8)
# Exemple 3: Action dynamique
video = gen.generate_video(
prompt="""
A golden retriever running through a flower field,
slow motion, sunset golden hour,
flowers blowing in the wind,
professional wildlife photography
"""
)
export_to_video(video, "dog_running.mp4", fps=8)
from diffusers import CogVideoXImageToVideoPipeline
from PIL import Image
# Charger pipeline I2V
pipe_i2v = CogVideoXImageToVideoPipeline.from_pretrained(
"THUDM/CogVideoX-5b-I2V",
torch_dtype=torch.float16
).to("cuda")
pipe_i2v.enable_model_cpu_offload()
pipe_i2v.vae.enable_slicing()
pipe_i2v.vae.enable_tiling()
# Image de départ
start_image = Image.open("portrait.jpg")
# Générer vidéo à partir de l'image
video = pipe_i2v(
prompt="The person smiles and waves at the camera",
image=start_image,
num_frames=49,
num_inference_steps=50,
guidance_scale=6.0
).frames[0]
export_to_video(video, "animated_portrait.mp4", fps=8)
Technique pour animer Stable Diffusion (ajouter motion aux images SD).
pip install diffusers[torch] transformers
from diffusers import AnimateDiffPipeline, MotionAdapter, DDIMScheduler
from diffusers.utils import export_to_video
import torch
# Charger MotionAdapter (module temporel)
adapter = MotionAdapter.from_pretrained(
"guoyww/animatediff-motion-adapter-v1-5-2",
torch_dtype=torch.float16
)
# Charger SD 1.5 + adapter
pipe = AnimateDiffPipeline.from_pretrained(
"runwayml/stable-diffusion-v1-5",
motion_adapter=adapter,
torch_dtype=torch.float16
).to("cuda")
# Utiliser DDIM scheduler
pipe.scheduler = DDIMScheduler.from_config(
pipe.scheduler.config,
beta_schedule="linear",
steps_offset=1,
clip_sample=False
)
# Générer animation
output = pipe(
prompt="A magical castle in the clouds, camera zoom out, epic fantasy, volumetric lighting",
negative_prompt="bad quality, blur, low resolution",
num_frames=16,
guidance_scale=7.5,
num_inference_steps=25
)
export_to_video(output.frames[0], "castle_animation.mp4", fps=8)
# Utiliser avec LoRA custom
pipe.load_lora_weights("path/to/style.safetensors")
output = pipe(
prompt="A cute anime character waving, ",
num_frames=16
)
Maintenir la cohérence des objets/personnages entre frames.
| Résolution | Durée Max | VRAM Requise | Temps Génération |
|---|---|---|---|
| 480p (720x480) | 6-10s | 18-30GB | 5-15 min |
| 720p (1280x720) | 4-6s | 40-48GB | 15-30 min |
| 1080p (1920x1080) | 2-4s | 80GB+ | 30-60 min |
Analyser et comprendre le contenu vidéo avec des VLM.
# Utiliser un VLM pour analyser une vidéo
from transformers import LlavaNextVideoForConditionalGeneration, LlavaNextVideoProcessor
import cv2
import torch
model = LlavaNextVideoForConditionalGeneration.from_pretrained(
"llava-hf/LLaVA-NeXT-Video-7B-hf",
torch_dtype=torch.float16
).to("cuda")
processor = LlavaNextVideoProcessor.from_pretrained(
"llava-hf/LLaVA-NeXT-Video-7B-hf"
)
# Extraire frames de la vidéo
def extract_frames(video_path, num_frames=8):
"""Extrait N frames uniformément espacées"""
cap = cv2.VideoCapture(video_path)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
indices = np.linspace(0, total_frames - 1, num_frames, dtype=int)
frames = []
for idx in indices:
cap.set(cv2.CAP_PROP_POS_FRAMES, idx)
ret, frame = cap.read()
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frames.append(Image.fromarray(frame))
cap.release()
return frames
# Analyser vidéo
frames = extract_frames("video.mp4", num_frames=8)
prompt = "Décris ce qui se passe dans cette vidéo en détail."
inputs = processor(
text=prompt,
images=frames,
return_tensors="pt"
).to("cuda")
output = model.generate(**inputs, max_new_tokens=256)
description = processor.decode(output[0], skip_special_tokens=True)
print("📹 Analyse vidéo:", description)
Les modèles multimodaux unifiés peuvent accepter et générer plusieurs modalités (texte, image, audio, vidéo) dans une seule architecture.
PaliGemma est la version vision-language de Gemma, optimisée pour VQA, captioning, OCR.
pip install transformers torch pillow
from transformers import AutoProcessor, PaliGemmaForConditionalGeneration
from PIL import Image
import torch
class PaliGemmaVision:
def __init__(self, model_size="3b-mix-448"):
"""
Initialise PaliGemma
Args:
model_size: 3b-pt-224, 3b-mix-448, 3b-pt-896
"""
model_id = f"google/paligemma-{model_size}"
self.device = "cuda" if torch.cuda.is_available() else "cpu"
self.model = PaliGemmaForConditionalGeneration.from_pretrained(
model_id,
torch_dtype=torch.bfloat16
).to(self.device)
self.processor = AutoProcessor.from_pretrained(model_id)
def query(self, image_path, prompt, max_tokens=256):
"""
Question sur une image
Args:
image_path: Chemin image
prompt: Question ou task (describe, detect, segment, etc.)
"""
image = Image.open(image_path).convert("RGB")
inputs = self.processor(
text=prompt,
images=image,
return_tensors="pt"
).to(self.device)
with torch.no_grad():
output = self.model.generate(
**inputs,
max_new_tokens=max_tokens,
do_sample=False
)
response = self.processor.decode(output[0], skip_special_tokens=True)
return response
# Utilisation
pali = PaliGemmaVision()
# Tâches supportées
tasks = {
"caption": "caption en", # Description courte
"detailed_caption": "describe en detail", # Description détaillée
"detect": "detect person ; dog", # Détection objets (bounding boxes)
"segment": "segment car", # Segmentation
"ocr": "ocr", # OCR
"answer": "question answering en What is the weather?" # VQA
}
for task_name, prompt in tasks.items():
result = pali.query("photo.jpg", prompt)
print(f"{task_name}: {result}")
2024 Modèle multimodal de Mistral AI avec support natif images + texte.
pip install mistral-inference
from mistral_inference.transformer import Transformer
from mistral_inference.generate import generate
from mistral_common.tokens.tokenizers.mistral import MistralTokenizer
from mistral_common.protocol.instruct.messages import UserMessage, ImageChunk, TextChunk
from PIL import Image
import base64
from io import BytesIO
class PixtralMultimodal:
def __init__(self):
"""Initialise Pixtral 12B"""
self.tokenizer = MistralTokenizer.from_model("pixtral")
self.model = Transformer.from_folder("path/to/pixtral-12b")
def image_to_base64(self, image_path):
"""Convertit image en base64 pour Pixtral"""
img = Image.open(image_path)
buffered = BytesIO()
img.save(buffered, format="PNG")
return base64.b64encode(buffered.getvalue()).decode()
def query(self, image_path, prompt):
"""Question multimodale"""
img_b64 = self.image_to_base64(image_path)
messages = [
UserMessage(
content=[
ImageChunk(image=img_b64),
TextChunk(text=prompt)
]
)
]
tokens = self.tokenizer.encode_chat_completion(messages).tokens
out_tokens, _ = generate(
[tokens],
self.model,
max_tokens=512,
temperature=0.0,
eos_id=self.tokenizer.instruct_tokenizer.tokenizer.eos_id
)
result = self.tokenizer.decode(out_tokens[0])
return result
# Alternative: Via Mistral API (hosted)
from mistralai import Mistral
import os
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
def query_pixtral_api(image_path, prompt):
"""Utiliser Pixtral via API Mistral"""
with open(image_path, "rb") as f:
img_b64 = base64.b64encode(f.read()).decode()
messages = [
{
"role": "user",
"content": [
{"type": "text", "text": prompt},
{"type": "image_url", "image_url": f"data:image/jpeg;base64,{img_b64}"}
]
}
]
response = client.chat.complete(
model="pixtral-12b-2409",
messages=messages
)
return response.choices[0].message.content
result = query_pixtral_api("chart.png", "Analyse ce graphique")
Modèle audio multilingue de Qwen pour analyse audio + génération texte.
from transformers import Qwen2AudioForConditionalGeneration, AutoProcessor
import torch
model = Qwen2AudioForConditionalGeneration.from_pretrained(
"Qwen/Qwen2-Audio-7B-Instruct",
torch_dtype=torch.bfloat16
).to("cuda")
processor = AutoProcessor.from_pretrained("Qwen/Qwen2-Audio-7B-Instruct")
# Tâches supportées
conversation = [
{
"role": "user",
"content": [
{"type": "audio", "audio_url": "audio.wav"},
{"type": "text", "text": "Transcris et résume cet audio."}
]
}
]
text = processor.apply_chat_template(conversation, add_generation_prompt=True, tokenize=False)
audios = processor.process_audio_urls([{"audio_url": "audio.wav"}])
inputs = processor(text=text, audios=audios, return_tensors="pt").to("cuda")
output = model.generate(**inputs, max_new_tokens=512)
result = processor.decode(output[0], skip_special_tokens=True)
print("Analyse audio:", result)
| Modèle | Architecture | Modalités | Forces |
|---|---|---|---|
| LLaVA | CLIP → Linear → LLM | Image + Text | Simple, efficace, fine-tunable |
| Qwen2-VL | Dynamic ViT → QFormer → Qwen | Image + Text | Multi-images, haute résolution, multilangue |
| InternVL | InternViT-6B → MLP → InternLM | Image + Text | SOTA benchmarks, scaling (1B-76B) |
| PaliGemma | SigLIP → Linear → Gemma | Image + Text | Tasks spécialisés (detect, segment, OCR) |
| Pixtral | Vision Encoder → Mistral | Image + Text | Intégration native, prompt long (128k) |
| Qwen2-Audio | Audio Encoder → Qwen | Audio + Text | Analyse audio, transcription, compréhension |
class UnifiedMultimodalAgent:
"""Agent unifié gérant texte, image, audio, vidéo"""
def __init__(self):
# Vision-Language
self.vlm = LlavaNextForConditionalGeneration.from_pretrained(
"llava-hf/llava-v1.6-mistral-7b-hf",
torch_dtype=torch.float16
).to("cuda")
# Audio (STT + TTS)
self.stt = WhisperSTT(model_size="medium")
self.tts = TTS("tts_models/multilingual/multi-dataset/xtts_v2")
# Texte (LLM)
from transformers import pipeline
self.llm = pipeline(
"text-generation",
model="mistralai/Mistral-7B-Instruct-v0.3",
device="cuda"
)
def process_multimodal_query(
self,
text_query=None,
image_path=None,
audio_path=None
):
"""
Traite une requête multimodale
Exemples:
- Texte seul: "Explique-moi la photosynthèse"
- Image + Texte: image="photo.jpg", text="Que vois-tu?"
- Audio: audio="question.wav" (converti en texte puis traité)
- Multi: audio + image (transcrit audio puis analyse image)
"""
# 1. Traiter l'audio si présent (STT)
if audio_path:
transcription = self.stt.transcribe(audio_path)
text_query = transcription["text"]
print(f"🎙️ Transcription: {text_query}")
# 2. Traiter l'image si présente (VLM)
if image_path and text_query:
print("👁️ Analyse multimodale image + texte...")
response = self.vlm_query(image_path, text_query)
# 3. Sinon, LLM texte seul
elif text_query:
print("💬 Traitement texte seul...")
messages = [{"role": "user", "content": text_query}]
response = self.llm(messages, max_new_tokens=300)[0]["generated_text"][-1]["content"]
else:
response = "Aucune entrée fournie."
return response
def vlm_query(self, image_path, prompt):
"""Helper pour VLM"""
# Code VLM simplifié
# ... (voir leçon 0)
pass
# Utilisation
agent = UnifiedMultimodalAgent()
# Cas 1: Question vocale
response = agent.process_multimodal_query(
audio_path="question.wav"
)
# Cas 2: Analyse image
response = agent.process_multimodal_query(
text_query="Décris cette scène",
image_path="landscape.jpg"
)
# Cas 3: Audio + Image
response = agent.process_multimodal_query(
audio_path="question_about_image.wav",
image_path="diagram.png"
)
print("🤖 Réponse:", response)
Document AI combine OCR, layout analysis, et compréhension sémantique pour extraire et structurer l'information de documents (PDF, scans, images).
OCR classique, excellent pour documents imprimés de qualité.
# Installation
# Windows: https://github.com/UB-Mannheim/tesseract/wiki
# Linux: sudo apt install tesseract-ocr tesseract-ocr-fra
pip install pytesseract pillow pdf2image
import pytesseract
from PIL import Image
from pdf2image import convert_from_path
class TesseractOCR:
def __init__(self, lang="fra+eng"):
"""
Initialise Tesseract
Args:
lang: Langues (fra, eng, deu, etc.) combinables avec +
"""
# Spécifier chemin Tesseract si Windows
# pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
self.lang = lang
def ocr_image(self, image_path, config=""):
"""OCR sur une image"""
img = Image.open(image_path)
text = pytesseract.image_to_string(img, lang=self.lang, config=config)
return text
def ocr_with_boxes(self, image_path):
"""OCR avec bounding boxes (coordonnées)"""
img = Image.open(image_path)
data = pytesseract.image_to_data(img, lang=self.lang, output_type=pytesseract.Output.DICT)
# Filtrer résultats (conf > 60)
results = []
for i in range(len(data["text"])):
if int(data["conf"][i]) > 60:
results.append({
"text": data["text"][i],
"bbox": (data["left"][i], data["top"][i],
data["width"][i], data["height"][i]),
"confidence": data["conf"][i]
})
return results
def ocr_pdf(self, pdf_path, dpi=300):
"""OCR sur PDF (converti en images d'abord)"""
pages = convert_from_path(pdf_path, dpi=dpi)
full_text = []
for i, page in enumerate(pages):
print(f"📄 OCR page {i+1}/{len(pages)}")
text = pytesseract.image_to_string(page, lang=self.lang)
full_text.append(f"=== Page {i+1} ===\n{text}")
return "\n\n".join(full_text)
# Utilisation
ocr = TesseractOCR(lang="fra+eng")
# Image simple
text = ocr.ocr_image("document.png")
print(text)
# Avec coordonnées (pour layout preservation)
boxes = ocr.ocr_with_boxes("invoice.jpg")
for box in boxes[:10]:
print(f"{box['text']} @ {box['bbox']} (conf: {box['confidence']}%)")
# PDF complet
text = ocr.ocr_pdf("contract.pdf")
with open("contract_extracted.txt", "w", encoding="utf-8") as f:
f.write(text)
OCR deep learning, meilleur pour écritures manuscrites et 80+ langues.
pip install easyocr
import easyocr
import cv2
import numpy as np
class EasyOCRExtractor:
def __init__(self, languages=["fr", "en"]):
"""Initialise EasyOCR (download models au 1er usage)"""
self.reader = easyocr.Reader(languages, gpu=True)
def ocr_image(self, image_path):
"""OCR avec EasyOCR"""
results = self.reader.readtext(image_path)
# results = [(bbox, text, confidence), ...]
extracted = []
for (bbox, text, conf) in results:
extracted.append({
"text": text,
"bbox": bbox,
"confidence": conf
})
return extracted
def visualize(self, image_path, output_path="annotated.jpg"):
"""Visualise les détections"""
img = cv2.imread(image_path)
results = self.reader.readtext(image_path)
for (bbox, text, conf) in results:
# Dessiner bbox
pts = np.array(bbox, dtype=np.int32)
cv2.polylines(img, [pts], True, (0, 255, 0), 2)
# Ajouter texte
cv2.putText(img, text, tuple(pts[0]),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)
cv2.imwrite(output_path, img)
print(f"✓ Visualisation sauvegardée: {output_path}")
# Utilisation
easy_ocr = EasyOCRExtractor(languages=["fr", "en"])
results = easy_ocr.ocr_image("handwritten.jpg")
for r in results:
print(f"{r['text']} (conf: {r['confidence']:.2f})")
# Visualisation
easy_ocr.visualize("form.jpg", "form_annotated.jpg")
Framework complet end-to-end de Mindee pour OCR + layout analysis.
pip install python-doctr[torch]
from doctr.io import DocumentFile
from doctr.models import ocr_predictor
import json
class DocTRProcessor:
def __init__(self):
"""Initialise DocTR (detección + OCR)"""
self.model = ocr_predictor(
det_arch="db_resnet50",
reco_arch="crnn_vgg16_bn",
pretrained=True
)
def process_document(self, file_path):
"""
Traite document (image ou PDF)
Returns:
dict structuré avec pages, blocs, lignes, mots
"""
# Charger document
doc = DocumentFile.from_images(file_path)
# OCR
result = self.model(doc)
# Exporter en dict
output = result.export()
return output
def extract_text(self, file_path):
"""Extrait uniquement le texte brut"""
output = self.process_document(file_path)
full_text = []
for page in output["pages"]:
page_text = []
for block in page["blocks"]:
for line in block["lines"]:
line_text = " ".join([word["value"] for word in line["words"]])
page_text.append(line_text)
full_text.append("\n".join(page_text))
return "\n\n".join(full_text)
def extract_structured(self, file_path):
"""Extrait avec structure (coordonnées, hiérarchie)"""
output = self.process_document(file_path)
structured = []
for page_idx, page in enumerate(output["pages"]):
page_data = {
"page": page_idx + 1,
"blocks": []
}
for block in page["blocks"]:
block_data = {
"geometry": block["geometry"],
"lines": []
}
for line in block["lines"]:
line_text = " ".join([w["value"] for w in line["words"]])
block_data["lines"].append({
"text": line_text,
"geometry": line["geometry"]
})
page_data["blocks"].append(block_data)
structured.append(page_data)
return structured
# Utilisation
doctr = DocTRProcessor()
# Extraction simple
text = doctr.extract_text("invoice.pdf")
print(text)
# Extraction structurée (pour layout-aware RAG)
structured = doctr.extract_structured("contract.pdf")
with open("contract_structured.json", "w", encoding="utf-8") as f:
json.dump(structured, f, indent=2, ensure_ascii=False)
pip install img2table camelot-py[cv]
# Option 1: img2table (images)
from img2table.document import Image as Img2TableImage
from img2table.ocr import TesseractOCR
def extract_tables_from_image(image_path):
"""Extrait tableaux d'une image"""
ocr = TesseractOCR(lang="fra+eng")
doc = Img2TableImage(src=image_path)
# Extraire tableaux
tables = doc.extract_tables(ocr=ocr)
# Convertir en DataFrame
import pandas as pd
dfs = []
for table in tables:
df = table.df
dfs.append(df)
return dfs
# Option 2: Camelot (PDF uniquement)
import camelot
def extract_tables_from_pdf(pdf_path):
"""Extrait tableaux d'un PDF"""
tables = camelot.read_pdf(pdf_path, pages="all", flavor="lattice")
dfs = []
for table in tables:
df = table.df
dfs.append(df)
return dfs
# Utilisation
tables = extract_tables_from_image("table.png")
for i, df in enumerate(tables):
print(f"Table {i+1}:")
print(df)
df.to_csv(f"table_{i+1}.csv", index=False)
Innovant Modèle transformer end-to-end qui comprend directement les documents sans OCR intermédiaire.
pip install donut-python
from transformers import DonutProcessor, VisionEncoderDecoderModel
from PIL import Image
import torch
class DonutDocumentAI:
def __init__(self, task="docvqa"):
"""
Initialise Donut
Args:
task: docvqa, cord-v2 (receipts), rvl-cdip (classification)
"""
model_map = {
"docvqa": "naver-clova-ix/donut-base-finetuned-docvqa",
"cord": "naver-clova-ix/donut-base-finetuned-cord-v2",
"rvl": "naver-clova-ix/donut-base-finetuned-rvlcdip"
}
model_name = model_map.get(task, model_map["docvqa"])
self.processor = DonutProcessor.from_pretrained(model_name)
self.model = VisionEncoderDecoderModel.from_pretrained(model_name).to("cuda")
def document_vqa(self, image_path, question):
"""
Visual Question Answering sur document
Args:
image_path: Document (scan, photo)
question: Question en langage naturel
"""
image = Image.open(image_path).convert("RGB")
# Préparer input
task_prompt = f"{question} "
pixel_values = self.processor(image, return_tensors="pt").pixel_values.to("cuda")
# Générer réponse
decoder_input_ids = self.processor.tokenizer(
task_prompt,
add_special_tokens=False,
return_tensors="pt"
).input_ids.to("cuda")
outputs = self.model.generate(
pixel_values,
decoder_input_ids=decoder_input_ids,
max_length=self.model.decoder.config.max_position_embeddings,
early_stopping=True,
pad_token_id=self.processor.tokenizer.pad_token_id,
eos_token_id=self.processor.tokenizer.eos_token_id,
use_cache=True,
num_beams=1,
bad_words_ids=[[self.processor.tokenizer.unk_token_id]],
return_dict_in_generate=True
)
# Décoder
sequence = self.processor.batch_decode(outputs.sequences)[0]
sequence = sequence.replace(self.processor.tokenizer.eos_token, "").replace(self.processor.tokenizer.pad_token, "")
sequence = sequence.split("")[-1].split(" ")[0].strip()
return sequence
# Utilisation
donut = DonutDocumentAI(task="docvqa")
# Questions sur une facture
questions = [
"What is the invoice number?",
"What is the total amount?",
"Who is the vendor?",
"What is the date?"
]
for q in questions:
answer = donut.document_vqa("invoice.jpg", q)
print(f"Q: {q}\nA: {answer}\n")
class DocumentAISystem:
"""Système complet de traitement de documents"""
def __init__(self):
self.doctr = DocTRProcessor()
self.donut = DonutDocumentAI()
self.table_extractor = extract_tables_from_image
def process_invoice(self, invoice_path):
"""
Pipeline complet pour facture
Returns:
dict avec toutes les infos extraites
"""
result = {
"raw_text": "",
"structured_fields": {},
"tables": [],
"metadata": {}
}
# 1. OCR complet
print("📄 Extraction texte...")
result["raw_text"] = self.doctr.extract_text(invoice_path)
# 2. Extraction champs structurés (VQA)
print("🔍 Extraction champs...")
fields_to_extract = {
"invoice_number": "What is the invoice number?",
"total_amount": "What is the total amount?",
"date": "What is the invoice date?",
"vendor": "Who is the vendor?",
"customer": "Who is the customer?"
}
for field, question in fields_to_extract.items():
answer = self.donut.document_vqa(invoice_path, question)
result["structured_fields"][field] = answer
# 3. Extraction tableaux
print("📊 Extraction tableaux...")
try:
tables = self.table_extractor(invoice_path)
result["tables"] = [df.to_dict() for df in tables]
except Exception as e:
print(f"⚠️ Erreur extraction tableaux: {e}")
return result
# Utilisation
doc_ai = DocumentAISystem()
invoice_data = doc_ai.process_invoice("invoice_scan.jpg")
print("Numéro facture:", invoice_data["structured_fields"]["invoice_number"])
print("Montant total:", invoice_data["structured_fields"]["total_amount"])
print("Nombre de tableaux:", len(invoice_data["tables"]))
# Sauvegarder résultat structuré
with open("invoice_data.json", "w") as f:
json.dump(invoice_data, f, indent=2)
L'IA spatiale combine vision 3D, génération de scènes 3D, et applications robotiques pour créer des systèmes qui comprennent et interagissent avec le monde physique.
NeRF représente des scènes 3D comme des champs de radiance neuronaux, permettant de synthétiser des vues photo-réalistes à partir de quelques photos 2D.
# Installation Nerfstudio (framework NeRF complet)
pip install nerfstudio
# Entraîner un NeRF à partir de photos
ns-train nerfacto --data path/to/images
# Render une vidéo
ns-render camera-path --load-config outputs/path/config.yml \
--camera-path-filename path/to/camera_path.json \
--output-path renders/output.mp4
# Alternative: Instant-NGP (ultra-rapide, NVIDIA)
# https://github.com/NVlabs/instant-ngp
pip install open3d
import open3d as o3d
import numpy as np
# Charger point cloud
pcd = o3d.io.read_point_cloud("scene.ply")
# Visualiser
o3d.visualization.draw_geometries([pcd])
# Segmentation avec RANSAC (détecter plan)
plane_model, inliers = pcd.segment_plane(
distance_threshold=0.01,
ransac_n=3,
num_iterations=1000
)
# Points du plan (ex: sol)
inlier_cloud = pcd.select_by_index(inliers)
inlier_cloud.paint_uniform_color([1, 0, 0])
# Points hors plan (objets)
outlier_cloud = pcd.select_by_index(inliers, invert=True)
o3d.visualization.draw_geometries([inlier_cloud, outlier_cloud])
Génération d'objets 3D à partir de texte ou images.
# Shap-E (OpenAI)
pip install shap-e
from shap_e.diffusion.sample import sample_latents
from shap_e.diffusion.gaussian_diffusion import diffusion_from_config
from shap_e.models.download import load_model, load_config
import torch
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# Charger modèle
xm = load_model('transmitter', device=device)
model = load_model('text300M', device=device)
diffusion = diffusion_from_config(load_config('diffusion'))
# Générer 3D à partir de texte
prompt = "a chair that looks like an avocado"
latents = sample_latents(
batch_size=1,
model=model,
diffusion=diffusion,
guidance_scale=15.0,
model_kwargs=dict(texts=[prompt]),
progress=True,
clip_denoised=True,
use_fp16=True,
use_karras=True,
karras_steps=64,
sigma_min=1e-3,
sigma_max=160,
s_churn=0,
)
# Export en .ply ou .obj
from shap_e.util.notebooks import decode_latent_mesh
for idx, latent in enumerate(latents):
mesh = decode_latent_mesh(xm, latent).tri_mesh()
with open(f'chair_{idx}.ply', 'wb') as f:
mesh.write_ply(f)
L'IA incarnée (embodied AI) intègre perception, raisonnement et action physique. Applications :
Quelle est la fonction principale de CLIP dans un VLM?
Quel avantage principal FLUX.1 schnell offre-t-il par rapport à SDXL?
Combien de langues Whisper large-v3 supporte-t-il approximativement?
Quelle est la durée minimum d'audio de référence pour cloner une voix avec XTTS v2?
Quel est le défi principal de la génération vidéo par IA?
Quelle caractéristique définit un modèle "any-to-any"?
Quelle est l'innovation principale de Donut par rapport aux pipelines OCR traditionnels?
Que permet de faire NeRF (Neural Radiance Fields)?
L'IA transforme la médecine : diagnostic assisté, analyse d'imagerie médicale, découverte de médicaments, personnalisation de traitements.
| Modèle | Base | Spécialisation | Performance |
|---|---|---|---|
| Med-PaLM 2 | PaLM | QA médical général | 85% MedQA (expert-level) |
| BioGPT | GPT-2 | Littérature biomédicale | PubMed fine-tuned |
| ClinicalBERT | BERT | Notes cliniques | Extraction entités médicales |
| Llama-3-Med | Llama 3 | Multi-tâches médical | Community fine-tuned |
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from transformers import pipeline
import torch
class MedicalRAGAssistant:
def __init__(self, medical_docs_path):
"""
Assistant médical avec RAG sur documentation médicale
IMPORTANT: Pour usage informatif uniquement, pas de diagnostic réel
"""
# Embeddings médicaux
self.embeddings = HuggingFaceEmbeddings(
model_name="microsoft/BiomedNLP-PubMedBERT-base-uncased-abstract"
)
# LLM médical
self.llm = pipeline(
"text-generation",
model="meta-llama/Meta-Llama-3-8B-Instruct",
torch_dtype=torch.float16,
device_map="auto"
)
# Charger documents médicaux
self.load_knowledge_base(medical_docs_path)
def load_knowledge_base(self, docs_path):
"""Charge et indexe la base de connaissances"""
# Charger documents (PDF, txt, etc.)
from langchain_community.document_loaders import DirectoryLoader
loader = DirectoryLoader(docs_path, glob="**/*.pdf")
docs = loader.load()
# Chunking
splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunks = splitter.split_documents(docs)
# Créer vector store
self.vectorstore = FAISS.from_documents(chunks, self.embeddings)
print(f"✓ Base médicale chargée: {len(chunks)} chunks")
def query(self, question, k=5):
"""
Répondre à une question médicale
Args:
question: Question médicale
k: Nombre de documents à récupérer
"""
# Récupérer contexte pertinent
docs = self.vectorstore.similarity_search(question, k=k)
context = "\n\n".join([doc.page_content for doc in docs])
# Prompt médical
prompt = f"""Tu es un assistant médical expert. Utilise le contexte suivant pour répondre à la question.
IMPORTANT:
- Réponds de manière précise et factuelle
- Cite les sources si possible
- Si tu n'es pas sûr, dis-le clairement
- Recommande toujours de consulter un professionnel de santé
Contexte médical:
{context}
Question: {question}
Réponse détaillée:"""
messages = [{"role": "user", "content": prompt}]
response = self.llm(
messages,
max_new_tokens=500,
temperature=0.3, # Basse pour précision
do_sample=True
)
answer = response[0]["generated_text"][-1]["content"]
return {
"answer": answer,
"sources": [doc.metadata for doc in docs]
}
# Utilisation
assistant = MedicalRAGAssistant("./medical_knowledge/")
result = assistant.query(
"Quels sont les symptômes et traitements de l'hypertension?"
)
print("Réponse:", result["answer"])
print("\nSources:", result["sources"])
import re
from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine
def anonymize_medical_text(text):
"""Anonymise informations sensibles dans texte médical"""
# Presidio (Microsoft) pour détection PII
analyzer = AnalyzerEngine()
anonymizer = AnonymizerEngine()
# Analyser
results = analyzer.analyze(
text=text,
language="fr",
entities=["PERSON", "LOCATION", "DATE_TIME", "PHONE_NUMBER", "EMAIL"]
)
# Anonymiser
anonymized = anonymizer.anonymize(
text=text,
analyzer_results=results
)
return anonymized.text
# Exemple
text = """
Patient: Jean Dupont, né le 15/03/1975
Adresse: 123 Rue de la Santé, Paris
Tel: 01 23 45 67 89
Diagnostic: Hypertension artérielle
"""
anonymized = anonymize_medical_text(text)
print(anonymized)
# Output: Patient: , né le
# Adresse:
# Tel:
# Diagnostic: Hypertension artérielle
Détection de fraude, analyse financière, trading algorithmique, compliance...
Analyse de contrats, extraction de clauses, recherche jurisprudentielle...
Tuteurs adaptatifs, génération de contenu pédagogique, évaluation automatisée...
Agents de code, revue automatique, tests intelligents, CI/CD amélioré...
Trouver des issues, écrire des PRs, code review, guidelines communautaires...
HuggingFace, AWS ML, GCP ML, structure portfolio, blog, speaking...
8 questions sur spécialisation & projets
Bias, fairness, transparency, explainability, frameworks IEEE/EU...
Classification des risques, obligations par niveau, documentation requise...
Modèles souverains, données locales, cloud souverain (Scaleway, OVH)...
Empreinte carbone, efficacité énergétique, calcul avec CodeCarbon...
Framework ROI, build vs buy, roadmap adoption, change management...
Reasoning models, world models, AGI debate, évolution régulation...
Concevez une architecture complète intégrant RAG + agents + fine-tuning + MLOps + monitoring
Évaluation finale couvrant les 8 phases de la formation