5 septembre 2023
Premiers pas avec Replicate
7 minutes de lecture
Introduction
Replicate est une plateforme mettant à disposition des outils et des centaines de modèles d’apprentissage, automatique, open-source et facilement intégrable dans nos projets. Son intégration ne nécessite pas de configuration particulière, juste la création d’un compte pour obtenir un jeton d’authentification.
Mais comme tout produit, Replicate possède des conditions tarifaires: la plateforme est accessible gratuitement mais peut devenir payante en fonction du nombre d’appels effectués à ses modèles.
Derrière ces modèles, Replicate utilise des algorithmes de "machine Learning" afin d’entrainer au mieux tous les modèles. Ces algorithmes ont pour objectif d’apprendre de façon autonome des tâches ou encore de réaliser des prédictions et d’améliorer leur propre performance. Ce processus peut s’avérer long et complexe car cela demande d’alimenter de façon conséquente un bon stock de données pour l’entrainement.
Heureusement pour nous, Replicate fait déjà tout cela pour nous.
Aperçu rapide des modèles
Pour explorer le reste de la collection 👉 🖼️
Comment utiliser et lancer un modèle ?
Ce service peut être interrogé de différentes manières. Nous pouvons retrouver plusieurs exemples d’intégration possibles depuis la documentation que nous fournit Replicate.
Prenons quelques exemples :
- via la librairie
Python
import replicate
output = replicate.run(
"stability-ai/stable-diffusion:db21e45d3f7023abc2a46ee38a23973f6dce16bb082a930b0c49861f96d1e5bf",
input={"prompt": "an astronaut riding on a horse"},
)
- via
Node.js
import Replicate from 'replicate'
const replicate = new Replicate({
auth: process.env.REPLICATE_API_TOKEN,
})
const model =
'stability-ai/stable-diffusion:db21e45d3f7023abc2a46ee38a23973f6dce16bb082a930b0c49861f96d1e5bf'
const input = { prompt: 'an astronaut riding a horse on mars, hd, dramatic lighting, detailed' }
const output = await replicate.run(model, { input })
console.log(output)
// ['https://pbxt.replicate.delivery/f4nlztv3uz1iFC4AEf2wBYQGTezdVeysvtZUtwfsvZOJDN6AC/out-0.png']
- Il est également possible d’utiliser la commande
curl
pour interroger un modèle.
$ curl -s -X POST \
-d '{"version": "db21e45d3f7023abc2a46ee38a23973f6dce16bb082a930b0c49861f96d1e5bf", \
"input": { "prompt": "an astronaut riding on a horse" } }' \
-H "Authorization: Token $REPLICATE_API_TOKEN" \
-H 'Content-Type: application/json' \
https://api.replicate.com/v1/predictions
Suivant vos projets, les modèles Replicate disponibles peuvent répondre à vos besoins et à vos attentes mais vous allez peut-être aussi souhaiter créer votre propre modèle ou entrainer un modèle en particulier avec vos propres données personnelles. Pas d’inquiétude, Replicate vous permet de le faire ! Si vous souhaitez en savoir plus, n’hésitez pas à faire un tour sur leur site.
A présent, illustrons tout cela avec un rapide projet React Native.
Démonstration dans une application React Native ⚙️
Afin de visualiser et de tester au mieux ce service, nous avons conçu rapidement une application mobile qui utilise le modèle stable-diffusion-v2-inpainting. Ce modèle nous permettra d’importer un décor aléatoire en se basant sur la position du visage.
Le principe est simple: prendre un photo en mode selfie grâce à la caméra sur le devant du téléphone, créer un masque qui délimitera la position du visage détecté, puis envoyer toutes les informations nécessaires à l’API.
C’est parti !
Tout d’abord, créer un compte sur le site Replicate afin d’obtenir un token
.
Pour en générer un, allez sur api-tokens depuis votre espace. Ce token sera à ajouter dans le header
des requêtes API.
const apiClient = axios.create({
baseURL: apiUrl,
headers: {
'Content-Type': 'application/json',
Authorization: `Token ${apiToken}`,
},
})
Prochaine étape, initialisation du projet react-native et installation des libraires pour implémenter la caméra et la détection faciale:
yarn add react-native-vision-camera
yarn add vision-camera-face-detector
npx expo install expo-face-detector
Il est possible que vous rencontriez comme moi quelques soucis lors de l’utilisation de certains composants de vision-camera-face-detector. > Pour palier ce problème, installer cette version de la librairie : "vision-camera-face-detector":"https://github.com/rodgomesc/vision-camera-face-detector#master"
Ajouter dans le fichier app.config.ts
, le plugin react-native-vision-camera
et la permission demandant l’accès à la caméra.
plugins: [
[
'react-native-vision-camera',
{
cameraPermissionText: '$(PRODUCT_NAME) needs access to your Camera.',
},
],
],
Pour toutes autres informations sur les installations, veuillez vous référencer aux documentations officielles.
Mise en place de la vue Camera
Si l’application n’a pas encore la permission requise pour accéder à la caméra du téléphone, il nous faudra l’obtenir grâce à la fonction requestCameraPermission
.
const hasPermission = await Camera.requestCameraPermission()
Détection et utilisation des objectifs caméra:
import { Camera, useCameraDevices, useFrameProcessor } from 'react-native-vision-camera'
const cameraRef = useRef<Camera>(null)
const devices = useCameraDevices('wide-angle-camera')
// utilisation de la caméra sur le devant du téléphone
const device = devices?.front
{
hasPermission === 'authorized' && (
<Camera
id="camera"
ref={cameraRef}
device={device}
frameProcessorFps={5}
photo={true}
video={false}
preset="photo"
/>
)
}
Pour la détection du visage, nous allons ajouter un frameProcessor
au composant Camera.
Les frameProcessors
sont des fonctions JavaScript ou TypeScript permettant de traiter les images aussi appelées frames, que la caméra “voit” en direct. Cela permet de détecter instantanément des éléments depuis l’objectif photo.
Ici nous allons demander à détecter un visage avec scanFaces
.
const frameProcessor = useFrameProcessor((frame: any) => {
'worklet';
const scannedFaces = scanFaces(frame);
// rappeler le threatJS pour stocker les valeurs du visage scanné
runOnJS(setFaces)(scannedFaces);
}, []);
<Camera
...
frameProcessor={frameProcessor}
/>
Pour respecter le formattage demandé par l’API, la photo sera recadrée au format 512x512 après la validation de la photo.
Pour se faire, nous avons utilisé la librairie react-native-image-crop-picker
qui, à partir du chemin de la photo stockée dans le téléphone, ouvrira les outils pour la transformation.
yarn add react-native-image-crop-picker
import ImagePicker from 'react-native-image-crop-picker'
const cropPhoto = async (path: string) => {
ImagePicker.openCropper({
mediaType: 'photo',
path: Platform.OS === 'android' ? 'file://' + path : path,
width: 512, // dimension souhaitée
height: 512,
includeBase64: true,
forceJpg: true,
}).then((photo) => {
/* les informations dans photo qui nous intéressent:
data : base64
mime: "image/jpeg"
path: "/private/var/mobile/Containers/Data/Application/F33FAD2F-088D-45BA-AAEC-9AD3F04A4E6D/tmp/react-native-image-crop-picker/FCABD78F-5B5D-4A02-AFEB-B13EF1A44B14.jpg",
size: 36110
*/
setPhotoPathCropped(photo.path)
setPhotoCropped(photo.data!)
})
}
return { photoPathCropped, photoCropped, cropPhoto }
La prochaine étape, la création du masque qui retrace la position du visage détecté.
Création du masque en noir et blanc
La partie recouverte de noir sera la zone à préserver et la partie blanche sera la zone où le modèle pourra agir et la transformer
Petit exemple de masque attendu à partir d’une photo avec visage:
Le masque est tout simplement une View
qui prend les coordonnées x et y avec la hauteur et largueur qui convient. Néanmoins, cette vue n’est pas encore récupérable.
Pour pouvoir l’envoyer à l’API, il nous faut la transformer en image.
Nous allons capturer la vue contenant le masque et la convertir en base64 à l’aide de cette react-native-view-shot:
yarn add react-native-view-shot
// Ajouter une référence au composant parent contenant le masque
const refCaptureSVG = useRef<View>(null)
;<View ref={refCaptureSVG}>// la box qui retrace la position du visage ...</View>
import { captureRef } from 'react-native-view-shot'
const useCaptureSVG = () => {
const [photoMask, setImageMask] = useState('')
const createSnapshotSVGtoIMG = async (ref: React.RefObject<View>) => {
const result = await captureRef(ref, {
result: 'base64',
quality: 1,
})
// formatter le résultat: retirer tous espaces et sauts de ligne
const base64 = result.replace(/\r?\n|\r/g, '')
setImageMask(base64)
}
return { photoMask, createSnapshotSVGtoIMG }
}
export default useCaptureSVG
Replicate ne supporte malheureusement pas le format base64
pour le champ mask
.
Pour palier ce soucis, nous avons héberger les masques créés dans un hébergeur d’images: un S3
de chez AWS.
Une fois ces 2 éléments créés, il nous reste plus qu’à spécifier quel style Replicate doit appliquer sur la photo. Depuis un formulaire, l’utilisateur pourra exprimer son désir créatif (dans le champ prompt
) ainsi que renseigner des paramètres pour le traitement de l’image (paramètres non obligatoires).
prompt_strength
: correspondant à la destruction complète ou partielle des informations dans l'image (min: 0 - max: 1.0)num_outputs
: nombre d'images à produire (min: 1 - max: 8)num_inference_steps
: nombre d'étapes de débruitage (min: 1 - max: 500)guidance_scale
: échelle pour un guidage sans classificateur (min: 1 - max: 20)seed
: graine aléatoire (valeur vide par défaut)
La partie formulaire est terminée, ne reste plus qu’à tout envoyer à l’API de Replicate.
Création d’une prédiction
Une prediction
correspond à une nouvelle demande de création à partir du modèle Replicate sélectionné. Celui-ci sera reconnu grâce à la version envoyée depuis le body
de la requête.
export type PredictionParams = {
prompt: string
image: string // base64 format
mask: string // url
num_inference_steps: string
num_outputs: string
prompt_strength: string
guidance_scale: string
}
export const createPrediction = (prediction: PredictionParams) => {
const inputPrediction = {
...prediction.input,
num_inference_steps: +prediction.input.num_inference_steps,
num_outputs: +prediction.input.num_outputs,
prompt_strength: +prediction.input.prompt_strength,
guidance_scale: +prediction.input.guidance_scale,
}
return apiClient.post<PredictionResponseSchemaData>(
'https://api.replicate.com/v1/predictions',
{
// version que vous allez pouvoir retrouver dans les exemples API du modèle sur le site
version: 'f9bb0632bfdceb83196e85521b9b55895f8ff3d1d3b487fd1973210c0eb30bec',
input: inputPrediction,
},
{
schema: PredictionResponseSchema,
}
)
}
La requête sera traitée par Replicate pendant quelques secondes et sera accessible depuis votre dashboard. Une liste de vos prédictions récentes y sera affichée.
Les prédictions créées lors d’un appel API, ne sont accessibles que pendant une certaine durée limitée. Après cela, le détail de ces prédictions ne sera plus visible.
Après ces quelques secondes de patience, la nouvelle photo de profil pourra être récupérée et être admirée.
Pour illustrer ce petit tuto, voici un exemple avec ma photo de profil.
Prompt
utilisé : closeup portrait of me with comic art style, neon city in the background, high resolution.
Conclusion
Replicate est un outil parfait si vous désirez apporter une touche d'originalité à vos photos. Et pas d'inquiètude, la documentation regorge d'exemples illustrés pour combler tous vos besoins et si vous souhaitez l'intégrer à vos projets, aucun soucis nous sommes là !
Bonne séance photo ! 👋