Dipublikasikan: 13 November 2024
Ujaran kebencian, pelecehan, dan pelecehan online telah menjadi masalah yang meluas di internet. Komentar beracun membungkam suara penting dan mengusir pengguna dan pelanggan. Deteksi konten beracun melindungi pengguna Anda dan menciptakan lingkungan online yang lebih aman.
Dalam serial dua bagian ini, kita akan mempelajari cara menggunakan AI untuk mendeteksi dan mengurangi konten beracun di sumbernya: keyboard pengguna.
Di bagian satu, kita telah membahas kasus penggunaan dan manfaat pendekatan ini.
Di bagian kedua ini, kita akan membahas implementasi, 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 menggunakan model machine learning di browser. Kode demo kami berasal dari contoh klasifikasi teks ini.
Kami memilih model toxic-bert, yaitu model terlatih sebelumnya yang dirancang untuk mengidentifikasi pola bahasa negatif. 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 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 berperforma lebih tinggi). Jalankan benchmark 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 dimaksud dengan komentar
toksik. Nilai minimum yang biasa digunakan adalah 0.9
. Dengan begitu, Anda dapat menemukan komentar yang sangat bersifat
toksik, sekaligus menghindari sensitivitas yang berlebihan yang dapat menyebabkan terlalu banyak
hasil positif palsu (dengan kata lain, komentar tidak berbahaya yang dikategorikan sebagai toksik).
export const TOXICITY_THRESHOLD = 0.9
Mengimpor komponen
Kita mulai dengan mengimpor komponen yang diperlukan dari library
@xenova/transformers
. Kami juga mengimpor konstanta dan nilai konfigurasi, termasuk
nilai ambang 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
klasifikasi. Versi yang paling tidak kompleks adalah
const classifier = await pipeline('text-classification', MODEL_NAME);
Membuat pipeline, seperti dalam contoh kode, adalah langkah pertama untuk menjalankan tugas inferensi.
Fungsi pipeline menggunakan 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. API ini menangani tugas seperti pemuatan model, tokenisasi, dan pascapemrosesan.
Kode demo kita melakukan lebih dari sekadar menyiapkan model, karena kita mengalihkan langkah-langkah persiapan model yang mahal secara komputasi ke pekerja web. Hal ini memungkinkan thread utama tetap responsif. Pelajari lebih lanjut cara mengalihkan tugas yang mahal ke pekerja web.
Pekerja kita perlu berkomunikasi dengan thread utama, menggunakan pesan untuk menunjukkan status model dan hasil penilaian toksisitas. Lihat kode pesan yang telah kita buat yang dipetakan ke berbagai status siklus proses inferensi dan persiapan 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 sebelumnya kita buat untuk menganalisis komentar pengguna. Kita menampilkan output mentah 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, kita memicu pengklasifikasi segera setelah pengguna berhenti mengetik
(lihat TYPING_DELAY
). Jika hal ini terjadi, thread utama kita akan 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
Kita akan memeriksa apakah skor output pengklasifikasi melebihi nilai minimum. Jika ya, kita akan mencatat label yang dimaksud.
Jika ada label toksisitas yang tercantum, komentar akan ditandai sebagai berpotensi toksik.
// 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 tidak menggunakan
jenis toksisitas yang lebih terperinci, tetapi kami telah menyediakannya untuk thread utama jika diperlukan (toxicityTypeList
). Anda mungkin
menemukan jenis ini berguna untuk kasus penggunaan Anda.
Pengalaman pengguna
Dalam demo, 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 (sehingga tidak menawarkan penilaian toksisitas), dan meskipun komentar terdeteksi sebagai negatif. Seperti yang direkomendasikan, Anda harus memiliki sistem kedua untuk mendeteksi komentar negatif. Jika sesuai untuk aplikasi Anda, pertimbangkan untuk memberi tahu pengguna bahwa komentar mereka telah diproses di klien, tetapi kemudian ditandai di server atau selama pemeriksaan manual.
- Perhatikan negatif palsu. Jika komentar tidak diklasifikasikan sebagai negatif, demo kami tidak akan memberikan masukan (misalnya, "Komentar bagus!"). Selain berisi derau, memberikan masukan positif dapat mengirimkan sinyal yang salah, karena pengklasifikasi kami terkadang, tetapi pasti, melewatkan beberapa komentar negatif.
Peningkatan dan alternatif
Batasan dan peningkatan 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.
- Nuance: Meskipun toxic-bert secara efektif mendeteksi toksisitas yang jelas, model ini mungkin mengalami kesulitan dengan kasus yang lebih halus atau bergantung pada konteks (ironi, sarkasme). Toksisitas dapat bersifat sangat subjektif dan halus. Misalnya, Anda mungkin ingin istilah tertentu atau bahkan emoji diklasifikasikan sebagai beracun. Penyesuaian dapat membantu meningkatkan akurasi di area ini.
Kami akan menerbitkan artikel tentang cara menyesuaikan 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 diambil, tetapi belum dioptimalkan dalam beberapa waktu, sehingga Anda mungkin melihat inferensi agak lebih lambat daripada dengan Transformers.js.
Kesimpulan
Deteksi konten beracun sisi klien adalah alat yang 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 beracun dan mengurangi beban klasifikasi toksisitas di server Anda.
Pendekatan sisi klien ini sudah berfungsi di seluruh browser. Namun, perhatikan 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.