AI ਡੈਮੋ ਹਰ ਪਾਸੇ ਹਨ। ਇੱਕ ਸਿੰਗਲ Python ਸਕ੍ਰਿਪਟ ਇੱਕ ਸਥਿਰ ਫੋਟੋ ਵਿੱਚ ਚਿਹਰਾ ਬਦਲ ਸਕਦੀ ਹੈ, ਅਤੇ ਨਤੀਜਾ ਜਾਦੂਈ ਲੱਗਦਾ ਹੈ। ਪਰ ਕੁਝ ਅਜਿਹਾ ਬਣਾਉਣਾ ਜਿਸ 'ਤੇ ਅਸਲੀ ਲੋਕ ਅਸਲ ਵਿੱਚ ਅਪਲੋਡ ਕਰ ਸਕਣ, ਉਸ ਤੋਂ ਦੂਰ ਜਾ ਸਕਣ, ਅਤੇ ਵਾਪਸ ਆ ਸਕਣ? ਉਹ ਇੱਕ ਬਿਲਕੁਲ ਵੱਖਰਾ ਕੰਮ ਹੈ। ਮੈਂ ਹਾਲ ਹੀ ਵਿੱਚ ਇੱਕ ਵੈੱਬ ਟੂਲ ਬਣਾਇਆ ਹੈ ਜੋ ਇੱਕ ਐਨੀਮੇਟਡ GIF ਅਤੇ ਇੱਕ ਰੈਫਰੈਂਸ ਚਿਹਰਾ ਲੈਂਦਾ ਹੈ, ਅਤੇ ਫਿਰ ਹਰ ਫਰੇਮ ਵਿੱਚ ਚਿਹਰਾ ਬਦਲ ਕੇ ਉਹੀ ਐਨੀਮੇਸ਼ਨ ਵਾਪਸ ਕਰਦਾ ਹੈ। ਮਾਡਲ ਵਿਜ਼ੂਅਲ ਭਾਰੀ ਕੰਮ ਕਰਦਾ ਹੈ, ਫਿਰ ਵੀ ਅਸਲ ਇੰਜੀਨੀਅਰਿੰਗ ਕੋਸ਼ਿਸ਼ ਇਸ ਦੇ ਆਲੇ-ਦੁਆਲੇ ਦੇ ਆਰਕੀਟੈਕਚਰ ਵਿੱਚ ਲੱਗੀ: ਕਨੈਕਸ਼ਨਾਂ ਨੂੰ ਜਿਉਂਦਾ ਰੱਖਣਾ, ਪੇਜ ਰਿਫ੍ਰੈਸ਼ ਹੋਣ 'ਤੇ ਵੀ ਚੱਲਦੇ ਰਹਿਣਾ, ਅਤੇ ਇਹ ਯਕੀਨੀ ਬਣਾਉਣਾ ਕਿ ਦੋ ਮਿੰਟ ਦਾ ਇਨਫਰੈਂਸ (inference) ਜੌਬ 504 Gateway Timeout ਵਿੱਚ ਗਾਇਬ ਨਾ ਹੋ ਜਾਵੇ।
ਇਹ ਇੱਕ ਪ੍ਰੋਟੋਟਾਈਪ ਅਤੇ ਇੱਕ ਉਤਪਾਦ (product) ਵਿਚਕਾਰ ਦਾ ਅੰਤਰ ਹੈ। ਇੰਜੀਨੀਅਰ ਡਿਫਿਊਜ਼ਨ ਆਰਕੀਟੈਕਚਰ (diffusion architectures) ਅਤੇ ਇਨਫਰੈਂਸ ਪੈਰਾਮੀਟਰਾਂ ਬਾਰੇ ਗੱਲ ਕਰਨਾ ਪਸੰਦ ਕਰਦੇ ਹਨ। ਪਰ ਜਦੋਂ ਕੋਈ ਯੂਜ਼ਰ 200 ਫਰੇਮਾਂ ਵਾਲਾ ਇੱਕ ਭਾਰੀ GIF ਅਪਲੋਡ ਕਰਦਾ ਹੈ, ਤਾਂ ਜੇਕਰ ਬ੍ਰਾਊਜ਼ਰ ਟੈਬ ਤਿਰਤੀ ਸਕਿੰਟਾਂ ਬਾਅਦ ਬੰਦ ਹੋ ਜਾਂਦਾ ਹੈ, ਤਾਂ ਕਿਸੇ ਨੂੰ ਤੁਹਾਡੇ ਮਾਡਲ ਦੀ ਪਰਵਾਹ ਨਹੀਂ ਹੁੰਦੀ। ਇਨਫਰੈਂਸ ਦੇ ਆਲੇ-ਦੁਆਲੇ ਦਾ ਇਨਫਰਾਸਟ੍ਰਕਚਰ ਉਨਾ ਹੀ ਮਹੱਤਵਪੂਰਨ ਹੈ ਜਿੰਨਾ ਕਿ ਇਨਫਰੈਂਸ ਖੁਦ।
ਇੰਤਜ਼ਾਰ ਕਰਨ ਦੀ ਸਮੱਸਿਆ
ਸਟੈਂਡਰਡ ਵੈੱਬ ਆਰਕੀਟੈਕਚਰ ਤੇਜ਼ ਜਵਾਬਾਂ ਦੀ ਉਮੀਦ ਕਰਦਾ ਹੈ। ਇੱਕ ਯੂਜ਼ਰ ਬਟਨ 'ਤੇ ਕਲਿੱਕ ਕਰਦਾ ਹੈ, ਸਰਵਰ ਜਵਾਬ ਦਿੰਦਾ ਹੈ, ਅਤੇ ਪੇਜ ਅਪਡੇਟ ਹੋ ਜਾਂਦਾ ਹੈ। ਦਰਜਨਾਂ GIF ਫਰੇਮਾਂ ਵਿੱਚ ਚਿਹਰਾ ਬਦਲਣਾ ਉਸ ਅਸੰਭਵ ਮੰਨਣ ਨੂੰ ਤੁਰੰਤ ਤੋੜ ਦਿੰਦਾ ਹੈ। ਮਾਡਲ Replicate ਦੇ GPUs 'ਤੇ ਚੱਲਦਾ ਹੈ, ਮੇਰੇ ਸਰਵਰ 'ਤੇ ਨਹੀਂ, ਅਤੇ ਇੱਕ ਲੰਬਾ GIF ਪ੍ਰੋਸੈਸ ਹੋਣ ਵਿੱਚ ਆਸਾਨੀ ਨਾਲ ਇੱਕ ਮਿੰਟ ਜਾਂ ਇਸ ਤੋਂ ਵੱਧ ਸਮਾਂ ਲੈ ਸਕਦਾ ਹੈ। ਜੇਕਰ ਤੁਸੀਂ ਇੰਨੀ ਦੇਰ ਤੱਕ HTTP ਰਿਕਵੈਸਟ ਨੂੰ ਖੁੱਲ੍ਹਾ ਰੱਖਣ ਦੀ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁਸੀਂ ਮੁਸੀਬਤ ਨੂੰ ਸੱਦਾ ਦੇ ਰਹੇ ਹੋ। Load balancers ਖਾਲੀ ਕਨੈਕਸ਼ਨਾਂ ਨੂੰ ਕੱਟ ਦਿੰਦੇ ਹਨ। ਬ੍ਰਾਊਜ਼ਰ ਮੰਨ ਲੈਂਦੇ ਹਨ ਕਿ ਨੈੱਟਵਰਕ ਫੇਲ ਹੋ ਗਿਆ ਹੈ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰਦੇ ਹਨ। ਯੂਜ਼ਰ ਇੱਕ ਰੁਕੇ ਹੋਏ ਸਪਿਨਰ ਨੂੰ ਦੇਖਦੇ ਰਹਿੰਦੇ ਹਨ ਅਤੇ ਮੰਨ ਲੈਂਦੇ ਹਨ ਕਿ ਐਪ ਖਰਾਬ ਹੋ ਗਈ ਹੈ।
ਮੈਂ ਸਬਮਿਸ਼ਨ ਨੂੰ ਨਤੀਜੇ ਤੋਂ ਵੱਖ ਕਰਕੇ ਇਸ ਤੋਂ ਪੂਰੀ ਤਰ੍ਹਾਂ ਬਚਿਆ। ਜਦੋਂ ਕੋਈ ਯੂਜ਼ਰ GIF ਅਤੇ ਚਿਹਰੇ ਦੀ ਤਸਵੀਰ ਅਪਲੋਡ ਕਰਦਾ ਹੈ, ਤਾਂ ਮੇਰਾ Next.js backend Replicate 'ਤੇ ਇੱਕ ਪ੍ਰੈਡਿਕਸ਼ਨ (prediction) ਸ਼ੁਰੂ ਕਰਦਾ ਹੈ ਅਤੇ ਤੁਰੰਤ ਇੱਕ job ID ਵਾਪਸ ਕਰ ਦਿੰਦਾ ਹੈ। ਯੂਜ਼ਰ ਨੂੰ ਤੁਰੰਤ ਪੁਸ਼ਟੀ ਮਿਲ ਜਾਂਦੀ ਹੈ। ਅਸਲ ਨਤੀਜਾ GPU ਕੰਮ ਖਤਮ ਹੋਣ ਤੋਂ ਬਾਅਦ ਇੱਕ webhook ਰਾਹੀਂ ਬਾਅਦ ਵਿੱਚ ਆਉਂਦਾ ਹੈ। ਇਹ ਪੈਟਰਨ ਕੋਈ ਅਜੀਬ ਚੀਜ਼ ਨਹੀਂ ਹੈ, ਪਰ ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਚੱਲਣ ਵਾਲੇ ਮੀਡੀਆ ਜੌਬਸ ਲਈ ਇਹ ਬਿਲਕੁਲ ਜ਼ਰੂਰੀ ਹੈ। ਇਹ ਇੱਕ ਅਨਿਸ਼ਚਿਤ ਇੰਤਜ਼ਾਰ ਨੂੰ ਇੱਕ ਭਰੋਸੇਮੰਦ ਹੱਥ ਮਿਲਾਉਣ (handshake) ਵਿੱਚ ਬਦਲ ਦਿੰਦਾ ਹੈ: ਜੌਬ ਸਵੀਕਾਰ ਕਰ ਲਈ ਗਈ ਹੈ, ਅਤੇ ਜਦੋਂ ਇਹ ਪੂਰੀ ਹੋ ਜਾਵੇਗੀ ਤਾਂ ਤੁਹਾਨੂੰ ਸੂਚਿਤ ਕੀਤਾ ਜਾਵੇਗਾ।
ਇੱਕ ਅਜਿਹੀ State Machine ਬਣਾਉਣਾ ਜਿਸ 'ਤੇ ਤੁਸੀਂ ਭਰੋਸਾ ਕਰ ਸਕੋ
ਇੱਕ ਵਾਰ ਜਦੋਂ ਤੁਸੀਂ asynchronous ਹੋ ਜਾਂਦੇ ਹੋ, ਤਾਂ ਤੁਹਾਨੂੰ ਦਿੱਖ (visibility) ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ। ਯੂਜ਼ਰ ਪੇਜ ਨੂੰ ਰਿਫ੍ਰੈਸ਼ ਕਰਨਗੇ। ਉਹ ਟੈਬ ਬੰਦ ਕਰਨਗੇ ਅਤੇ ਦੁਬਾਰਾ ਖੋਲ੍ਹਣਗੇ। ਉਹ ਲਿੰਕ ਕਾਪੀ ਕਰਨਗੇ ਅਤੇ ਆਪਣੇ ਕਿਸੇ ਸਾਥੀ ਨੂੰ ਭੇਜਣਗੇ ਜੋ ਦੋ ਘੰਟੇ ਬਾਅਦ ਇਸ ਦੀ ਜਾਂਚ ਕਰੇਗਾ। ਜੋ ਕੁਝ ਵੀ ਹੋਇਆ ਹੈ ਉਸਦਾ ਇੱਕ ਪੱਕਾ ਰਿਕਾਰਡ ਹੋਵੇ ਬਿਨਾਂ, ਸਭ ਕੁਝ ਉਲਝਣ ਵਾਲਾ ਹੋ ਜਾਵੇਗਾ।
ਮੈਂ Supabase ਨੂੰ 'single source of truth' ਵਜੋਂ ਵਰਤਿਆ। ਹਰ ਅਪਲੋਡ ਇੱਕ ਵਿਲੱਖਣ job ID ਦੇ ਨਾਲ ਇੱਕ ਰੋਅ (row) ਬਣਾਉਂਦਾ ਹੈ, ਅਤੇ ਉਹ ਰੋਅ ਖਾਸ ਸਟੇਟਸ (states) ਵਿੱਚੋਂ ਲੰਘਦੀ ਹੈ: queued, processing, succeeded, failed, ਜਾਂ expired। ਜਦੋਂ ਯੂਜ਼ਰ ਪਹਿਲੀ ਵਾਰ submit ਕਰਦਾ ਹੈ, ਤਾਂ ਰੋਅ queued ਹੁੰਦੀ ਹੈ। ਜਿਸ ਪਲ Replicate ਪ੍ਰੈਡਿਕਸ਼ਨ ਨੂੰ ਸਵੀਕਾਰ ਕਰਦਾ ਹੈ, ਇਹ processing ਵਿੱਚ ਬਦਲ ਜਾਂਦੀ ਹੈ। Webhook ਇਸ ਨੂੰ succeeded ਜਾਂ failed ਵਿੱਚ ਭੇਜ ਦਿੰਦਾ ਹੈ। ਮੈਂ ਉਹਨਾਂ ਜੌਬਸ ਲਈ expired ਜੋ ਬਿਨਾਂ ਕਿਸੇ ਕਾਲਬੈਕ ਦੇ ਬਹੁਤ ਦੇਰ ਤੱਕ ਰੁਕਦੇ ਹਨ, ਜੋੜਿਆ ਹੈ, ਤਾਂ ਜੋ ਸਿਸਟਮ ਬਿਨਾਂ ਵਜ੍ਹਾ ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਉਹਨਾਂ ਦੀ ਭਾਲ ਨਾ ਕਰਦਾ ਰਹੇ।
TypeScript ਵਿੱਚ ਬਣਾਇਆ ਗਿਆ frontend, ਥੋੜ੍ਹੇ ਸਮੇਂ ਦੇ ਅੰਤਰਾਲ 'ਤੇ Supabase ਨੂੰ poll ਕਰਦਾ ਹੈ ਅਤੇ ਜੋ ਵੀ ਮੌਜੂਦਾ ਸਟੇਟ ਦੱਸਦੀ ਹੈ, ਉਸ ਨੂੰ ਰੈਂਡਰ ਕਰਦਾ ਹੈ। ਇਹ polling ਦੇਖਣ ਵਿੱਚ ਬਹੁਤ ਸਾਧਾਰਨ ਲੱਗਦੀ ਹੈ, ਪਰ ਇਹ ਰਿਫ੍ਰੈਸ਼ ਦੀ ਸਮੱਸਿਆ ਨੂੰ ਪੂਰੀ ਤਰ੍ਹਾਂ ਹੱਲ ਕਰ ਦਿੰਦੀ ਹੈ। ਇੱਕ ਯੂਜ਼ਰ ਆਪਣਾ ਲੈਪਟਾਪ ਬੰਦ ਕਰ ਸਕਦਾ ਹੈ, ਕੱਲ੍ਹ ਇਸਨੂੰ ਖੋਲ੍ਹ ਸਕਦਾ ਹੈ, ਅਤੇ ਦੇਖ ਸਕਦਾ ਹੈ ਕਿ ਚੀਜ਼ਾਂ ਕਿੱਥੇ ਤੱਕ ਪਹੁੰਚੀਆਂ ਹਨ ਕਿਉਂਕਿ ਪ੍ਰ
ਇੱਕ ਡੈਮੋ ਨੂੰ ਅਜਿਹੇ ਸਾਫਟਵੇਅਰ ਵਿੱਚ ਬਦਲਣਾ ਜਿਸ 'ਤੇ ਲੋਕ ਭਰੋਸਾ ਕਰ ਸਕਣ
ਇੱਥੇ ਇੱਕ ਵੱਡਾ ਸਬਕ ਹੈ ਜੋ ਬਾਜ਼ਾਰ ਵਿੱਚ ਮੌਜੂਦ ਲਗਭਗ ਹਰ generative AI ਟੂਲ 'ਤੇ ਲਾਗੂ ਹੁੰਦਾ ਹੈ। ਮਾਡਲ ਆਪਣੇ ਆਪ ਵਿੱਚ ਕੰਮ ਦਾ ਸਿਰਫ਼ ਤੀਹ ਪ੍ਰਤੀਸ਼ਤ ਹੋ ਸਕਦਾ ਹੈ। ਬਾਕੀ ਸੱਤਰ ਪ੍ਰਤੀਸ਼ਤ ਉਹ ਗੈਰ-ਚਮਕਦਾਰ ਪਿਛਲੇ ਕੰਮ (plumbing) ਹਨ ਜਿਸ ਬਾਰੇ ਕੋਈ ਟਵੀਟ ਨਹੀਂ ਕਰਦਾ: state recovery, webhook signatures, file conversion, credit tracking, ਅਤੇ graceful failure।
ਮੇਰਾ stack ਸਰਲ ਅਤੇ ਸੋਚ-ਸਮਝ ਕੇ ਚੁਣਿਆ ਹੋਇਆ ਹੈ। Next.js ਅਤੇ TypeScript ਇੰਟਰਫੇਸ ਅਤੇ API ਰੂਟਸ ਨੂੰ ਸੰਭਾਲਦੇ ਹਨ। Replicate ਮਾਡਲਾਂ ਨੂੰ ਚਲਾਉਂਦਾ ਹੈ। Supabase ਸਟੇਟਸ, ਡੇਟਾ ਅਤੇ ਕ੍ਰੈਡਿਟਸ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਦਾ ਹੈ। FFmpeg WASM ਕਲਾਇੰਟ-ਸਾਈਡ ਮੀਡੀਆ ਕੰਮ ਸੰਭਾਲਦਾ ਹੈ। Animated WebP UI ਨੂੰ ਤੇਜ਼ ਰੱਖਦਾ ਹੈ। ਹਰ ਹਿੱਸੇ ਦਾ ਇੱਕ ਹੀ ਕੰਮ ਹੈ, ਅਤੇ ਉਹ ਕਮਜ਼ੋਰ, ਲੰਬੇ ਸਮੇਂ ਤੱਕ ਚੱਲਣ ਵਾਲੀਆਂ ਰਿਕੁਐਸਟਾਂ ਦੀ ਬਜਾਏ ਸਪੱਸ਼ਟ state transitions ਰਾਹੀਂ ਆਪਸ ਵਿੱਚ ਜੁੜਦੇ ਹਨ।
ਜਦੋਂ ਕੋਈ ਯੂਜ਼ਰ face swap ਲਈ ਕ੍ਰੈਡਿਟਸ ਦੀ ਵਰਤੋਂ ਕਰਦਾ ਹੈ, ਤਾਂ ਉਹ ਭਰੋਸੇਯੋਗਤਾ ਦੀ ਉਮੀਦ ਕਰਦਾ ਹੈ, ਕਿਸੇ ਰਿਸਰਚ ਪੇਪਰ ਦੀ ਨਹੀਂ। ਜੇਕਰ ਕੋਈ prediction ਫੇਲ੍ਹ ਹੋ ਜਾਂਦੀ ਹੈ, ਤਾਂ ਸਿਸਟਮ ਨੂੰ ਇਸਦਾ ਪਤਾ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ ਅਤੇ ਉਸਨੂੰ ਦੱਸਣਾ ਚਾਹੀਦਾ ਹੈ। ਜੇਕਰ ਯੂਜ਼ਰ ਉਡੀਕ ਕਰਦਾ ਹੈ, ਤਾਂ ਉਸ ਕੋਲ ਦੇਖਣ ਲਈ ਇੱਕ ਹਲਕਾ-ਫੁਲਕਾ preview ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ ਅਤੇ ਇੱਕ ਅਜਿਹਾ ਸਟੇਟਸ ਹੋਣਾ ਚਾਹੀਦਾ ਹੈ ਜੋ ਬ੍ਰਾਊਜ਼ਰ ਰੀਸਟਾਰਟ ਕਰਨ 'ਤੇ ਵੀ ਬਰਕਰਾਰ ਰਹੇ। ਜਦੋਂ ਇਹ ਕੰਮ ਕਰਦੇ ਹਨ ਤਾਂ ਇਹ ਵੇਰਵੇ ਅਣਦਿੱਖੇ ਹੁੰਦੇ ਹਨ, ਪਰ ਜਦੋਂ ਇਹ ਕੰਮ ਨਹੀਂ ਕਰਦੇ ਤਾਂ ਇਹ ਘਾਤਕ ਸਾਬਤ ਹੁੰਦੇ ਹਨ।
Face swap ਆਪਣੇ ਆਪ ਵਿੱਚ ਇੱਕ ਵਧੀਆ ਤਰੀਕਾ ਹੈ। ਪਰ ਇਹ ਟੂਲ ਉਦੋਂ ਹੀ ਅਸਲੀ ਲੱਗਦਾ ਹੈ ਜਦੋਂ ਯੂਜ਼ਰ ਆਪਣੀ ਜਗ੍ਹਾ ਗੁਆਏ ਬਿਨਾਂ ਅਪਲੋਡ ਕਰ ਸਕਦਾ ਹੈ, ਜਾ ਸਕਦਾ ਹੈ ਅਤੇ ਵਾਪਸ ਆ ਸਕਦਾ ਹੈ। ਇਹੀ ਉਹ ਚੀਜ਼ ਹੈ ਜੋ ਇੱਕ API ਕਾਲ ਨੂੰ ਅਜਿਹੇ ਸਾਫਟਵੇਅਰ ਵਿੱਚ ਬਦਲ ਦਿੰਦੀ ਹੈ ਜਿਸ 'ਤੇ ਲੋਕ ਅਸਲ ਵਿੱਚ ਭਰੋਸਾ ਕਰਦੇ ਹਨ।
