Dipublikasikan: 13 November 2024
Ujaran kebencian, pelecehan, dan penyalahgunaan online telah menjadi masalah yang meluas di internet. Komentar tidak pantas membungkam pendapat penting dan membuat pengguna dan pelanggan menjauh. Deteksi toksisitas melindungi pengguna Anda dan menciptakan lingkungan online yang lebih aman.
Dalam seri dua bagian ini, kita akan mempelajari cara menggunakan AI untuk mendeteksi dan mengurangi toksisitas di sumbernya: keyboard pengguna.
Di bagian pertama, kita membahas kasus penggunaan dan manfaat pendekatan ini.
Di bagian kedua ini, kita akan mempelajari implementasinya, termasuk contoh kode dan tips UX.
Demo dan kode
Coba demo kami dan pelajari kode di GitHub.
Dukungan browser
Demo kami berjalan di Safari, Chrome, Edge, dan Firefox versi terbaru.
Memilih model dan library
Kita menggunakan library Transformers.js Hugging Face, yang menyediakan alat untuk bekerja dengan model machine learning di browser. Kode demo kami berasal dari contoh klasifikasi teks ini.
Kami memilih model toxic-bert, yaitu model terlatih yang dirancang untuk mengidentifikasi pola bahasa negatif. Model ini adalah versi unitary/toxic-bert yang kompatibel dengan web. Untuk mengetahui detail selengkapnya tentang label model dan klasifikasi serangan identitasnya, lihat halaman model Hugging Face.
Setelah model didownload, inferensi akan berjalan cepat.
Misalnya, biasanya diperlukan waktu kurang dari 500 milidetik di Chrome yang berjalan di perangkat Android kelas menengah yang telah kami uji (ponsel Pixel 7 biasa, bukan model Pro yang lebih berperforma). Jalankan tolok ukur Anda sendiri yang mewakili basis pengguna Anda.
Penerapan
Berikut adalah langkah-langkah utama dalam penerapan kami:
Menetapkan nilai minimum toksisitas
Pengklasifikasi toksisitas kami memberikan skor toksisitas antara 0 dan 1. Dalam
rentang tersebut, kita perlu menetapkan nilai minimum untuk menentukan apa yang merupakan komentar
tidak sopan. Nilai minimum yang umum digunakan adalah 0.9. Dengan begitu, Anda dapat menemukan komentar yang jelas-jelas toksik, sekaligus menghindari sensitivitas berlebihan yang dapat menyebabkan terlalu banyak positif palsu (dengan kata lain, komentar tidak berbahaya dikategorikan sebagai toksik).
export const TOXICITY_THRESHOLD = 0.9
Impor komponen
Kita mulai dengan mengimpor komponen yang diperlukan dari library @xenova/transformers
library. Kita juga mengimpor konstanta dan nilai konfigurasi, termasuk
nilai batas toksisitas.
import { env, pipeline } from '@xenova/transformers';
// Model name: 'Xenova/toxic-bert'
// Our threshold is set to 0.9
import { TOXICITY_THRESHOLD, MODEL_NAME } from './config.js';
Memuat model dan berkomunikasi dengan thread utama
Kita memuat model deteksi toksisitas toxic-bert, dan menggunakannya untuk menyiapkan pengklasifikasi. Versi yang paling tidak rumit adalah
const classifier = await pipeline('text-classification', MODEL_NAME);
Membuat pipeline, seperti dalam contoh kode, adalah langkah pertama untuk menjalankan tugas inferensi.
Fungsi pipeline mengambil dua argumen: tugas ('text-classification')
dan model (Xenova/toxic-bert).
Istilah penting: Di Transformers.js, pipeline adalah API tingkat tinggi yang menyederhanakan proses menjalankan model ML. Class ini menangani tugas seperti pemuatan model, tokenisasi, dan pemrosesan pasca-pemrosesan.
Kode demo kita melakukan lebih dari sekadar menyiapkan model, karena kita mengalihkan langkah-langkah penyiapan model yang mahal secara komputasi ke pekerja web. Hal ini memungkinkan thread utama tetap responsif. Pelajari lebih lanjut cara menurunkan beban tugas berat ke web worker.
Worker kita perlu berkomunikasi dengan thread utama, menggunakan pesan untuk menunjukkan status model dan hasil penilaian toksisitas. Lihat kode pesan yang telah kami buat dan dipetakan ke berbagai status siklus proses penyiapan dan inferensi model.
let classifier = null;
(async function () {
// Signal to the main thread that model preparation has started
self.postMessage({ code: MESSAGE_CODE.PREPARING_MODEL, payload: null });
try {
// Prepare the model
classifier = await pipeline('text-classification', MODEL_NAME);
// Signal to the main thread that the model is ready
self.postMessage({ code: MESSAGE_CODE.MODEL_READY, payload: null });
} catch (error) {
console.error('[Worker] Error preparing model:', error);
self.postMessage({ code: MESSAGE_CODE.MODEL_ERROR, payload: null });
}
})();
Mengklasifikasikan input pengguna
Dalam fungsi classify, kita menggunakan pengklasifikasi yang dibuat sebelumnya untuk menganalisis komentar pengguna. Kami menampilkan output mentah dari pengklasifikasi toksisitas: label dan skor.
// Asynchronous function to classify user input
// output: [{ label: 'toxic', score: 0.9243140482902527 },
// ... { label: 'insult', score: 0.96187334060668945 }
// { label: 'obscene', score: 0.03452680632472038 }, ...etc]
async function classify(text) {
if (!classifier) {
throw new Error("Can't run inference, the model is not ready yet");
}
let results = await classifier(text, { topk: null });
return results;
}
Kita memanggil fungsi klasifikasi saat thread utama meminta pekerja untuk melakukannya.
Dalam demo ini, kita memicu pengklasifikasi segera setelah pengguna berhenti mengetik
(lihat TYPING_DELAY). Saat ini terjadi, thread utama kita mengirim pesan ke
pekerja yang berisi input pengguna untuk diklasifikasikan.
self.onmessage = async function (message) {
// User input
const textToClassify = message.data;
if (!classifier) {
throw new Error("Can't run inference, the model is not ready yet");
}
self.postMessage({ code: MESSAGE_CODE.GENERATING_RESPONSE, payload: null });
// Inference: run the classifier
let classificationResults = null;
try {
classificationResults = await classify(textToClassify);
} catch (error) {
console.error('[Worker] Error: ', error);
self.postMessage({
code: MESSAGE_CODE.INFERENCE_ERROR,
});
return;
}
const toxicityTypes = getToxicityTypes(classificationResults);
const toxicityAssessement = {
isToxic: toxicityTypes.length > 0,
toxicityTypeList: toxicityTypes.length > 0 ? toxicityTypes.join(', ') : '',
};
console.info('[Worker] Toxicity assessed: ', toxicityAssessement);
self.postMessage({
code: MESSAGE_CODE.RESPONSE_READY,
payload: toxicityAssessement,
});
};
Memproses output
Kami memeriksa apakah skor output pengklasifikasi melebihi nilai minimum kami. Jika ya, kami akan mencatat label yang dipermasalahkan.
Jika salah satu label toksisitas tercantum, komentar tersebut ditandai sebagai berpotensi negatif.
// input: [{ label: 'toxic', score: 0.9243140482902527 }, ...
// { label: 'insult', score: 0.96187334060668945 },
// { label: 'obscene', score: 0.03452680632472038 }, ...etc]
// output: ['toxic', 'insult']
function getToxicityTypes(results) {
const toxicityAssessment = [];
for (let element of results) {
// If a label's score > our threshold, save the label
if (element.score > TOXICITY_THRESHOLD) {
toxicityAssessment.push(element.label);
}
}
return toxicityAssessment;
}
self.onmessage = async function (message) {
// User input
const textToClassify = message.data;
if (!classifier) {
throw new Error("Can't run inference, the model is not ready yet");
}
self.postMessage({ code: MESSAGE_CODE.GENERATING_RESPONSE, payload: null });
// Inference: run the classifier
let classificationResults = null;
try {
classificationResults = await classify(textToClassify);
} catch (error) {
self.postMessage({
code: MESSAGE_CODE.INFERENCE_ERROR,
});
return;
}
const toxicityTypes = getToxicityTypes(classificationResults);
const toxicityAssessement = {
// If any toxicity label is listed, the comment is flagged as
// potentially toxic (isToxic true)
isToxic: toxicityTypes.length > 0,
toxicityTypeList: toxicityTypes.length > 0 ? toxicityTypes.join(', ') : '',
};
self.postMessage({
code: MESSAGE_CODE.RESPONSE_READY,
payload: toxicityAssessement,
});
};
Menampilkan petunjuk
Jika isToxic benar, kita akan menampilkan petunjuk kepada pengguna. Dalam demo kami, kami tidak menggunakan jenis toksisitas yang lebih terperinci, tetapi kami telah menyediakannya untuk thread utama jika diperlukan (toxicityTypeList). Anda mungkin menganggapnya berguna untuk kasus penggunaan Anda.
Pengalaman pengguna
Dalam demo kami, kami telah membuat pilihan berikut:
- Selalu izinkan postingan. Petunjuk toksisitas sisi klien kami tidak mencegah pengguna memposting. Dalam demo kami, pengguna dapat memposting komentar meskipun model belum dimuat (dan dengan demikian tidak menawarkan penilaian toksisitas), dan meskipun komentar tersebut terdeteksi sebagai komentar negatif. Seperti yang direkomendasikan, Anda harus memiliki sistem kedua untuk mendeteksi komentar negatif. Jika masuk akal untuk aplikasi Anda, pertimbangkan untuk memberi tahu pengguna bahwa komentarnya berhasil dikirim di klien, tetapi kemudian ditandai di server atau selama pemeriksaan manual.
- Perhatikan negatif palsu. Jika komentar tidak diklasifikasikan sebagai negatif, demo kami tidak memberikan masukan (misalnya, "Komentar yang bagus!"). Selain berisik, memberikan masukan positif dapat mengirimkan sinyal yang salah, karena pengklasifikasi kami terkadang, tetapi pasti melewatkan beberapa komentar negatif.
Peningkatan dan alternatif
Batasan dan peningkatan di masa mendatang
- Bahasa: Model yang kami gunakan terutama mendukung bahasa Inggris. Untuk dukungan multibahasa, Anda perlu melakukan penyesuaian. Beberapa model toksisitas yang tercantum di Hugging Face mendukung bahasa non-Inggris (Rusia, Belanda), meskipun saat ini tidak kompatibel dengan Transformers.js.
- Nuansa: Meskipun toxic-bert efektif mendeteksi toksisitas yang jelas, model ini mungkin kesulitan menangani kasus yang lebih halus atau bergantung pada konteks (ironi, sarkasme). Toksisitas bisa sangat subjektif dan halus. Misalnya, Anda mungkin ingin istilah atau bahkan emoji tertentu diklasifikasikan sebagai berbahaya. Penyesuaian dapat membantu meningkatkan akurasi di area ini.
Kami akan segera menerbitkan artikel tentang penyesuaian model toksisitas.
Alternatif
- MediaPipe untuk klasifikasi teks. Pastikan untuk menggunakan model yang kompatibel dengan tugas klasifikasi.
Pengklasifikasi toksisitas TensorFlow.js. Model ini menawarkan model yang lebih kecil dan lebih cepat untuk diambil, tetapi belum dioptimalkan selama beberapa waktu, sehingga Anda mungkin melihat inferensi yang agak lebih lambat daripada dengan Transformers.js.
Kesimpulan
Deteksi toksisitas sisi klien adalah alat canggih untuk meningkatkan kualitas komunitas online.
Dengan memanfaatkan model AI seperti toxic-bert yang berjalan di browser dengan Transformers.js, Anda dapat menerapkan mekanisme masukan real-time yang mencegah perilaku tidak pantas dan mengurangi beban klasifikasi perilaku tidak pantas di server Anda.
Pendekatan sisi klien ini sudah berfungsi di seluruh browser. Namun, perlu diingat batasannya, terutama dalam hal biaya penayangan model dan ukuran download. Terapkan praktik terbaik performa untuk AI sisi klien dan simpan model dalam cache.
Untuk deteksi toksisitas yang komprehensif, gabungkan pendekatan sisi klien dan sisi server.