Yayınlanma tarihi: 13 Kasım 2024
Nefret söylemi, taciz ve internette kötüye kullanım, internette yaygın bir sorun haline geldi. Kötü niyetli yorumlar önemli sesleri susturur ve kullanıcıları ve müşterileri uzaklaştırır. Zararlı içerik algılama özelliği, kullanıcılarınızı korur ve daha güvenli bir online ortam oluşturur.
İki bölümden oluşan bu seride, yapay zekayı kullanarak toksik içerikleri kaynağında (kullanıcıların klavyelerinde) nasıl tespit edip azaltacağımızı ele alıyoruz.
Birinci bölümde, bu yaklaşımın kullanım alanlarını ve avantajlarını ele aldık.
Bu ikinci bölümde, kod örnekleri ve kullanıcı deneyimi ipuçları da dahil olmak üzere uygulama konusunu ayrıntılı olarak ele alıyoruz.
Demo ve kod
Demomuzu inceleyin ve GitHub'daki kodu inceleyin.
Tarayıcı desteği
Demomuz Safari, Chrome, Edge ve Firefox'un en son sürümlerinde çalışır.
Model ve kitaplık seçme
Tarayıcıda makine öğrenimi modelleriyle çalışmak için araçlar sağlayan Hugging Face'in Transformers.js kitaplığını kullanıyoruz. Demo kodumuz bu metin sınıflandırma örneğinden türetilmiştir.
Zararlı dil kalıplarını belirlemek için tasarlanmış, önceden eğitilmiş bir model olan toxic-bert modelini seçiyoruz. unitary/toxic-bert'ün web ile uyumlu bir sürümüdür. Modelin etiketleri ve kimlik saldırılarını sınıflandırması hakkında daha fazla bilgi için Hugging Face model sayfasına bakın.
Model indirildikten sonra çıkarım hızlı bir şekilde yapılır.
Örneğin, test ettiğimiz orta seviye bir Android cihazda (daha yüksek performanslı Pro modeli değil, normal bir Pixel 7 telefonu) Chrome'da genellikle 500 milisaniyeden kısa sürer. Kullanıcı tabanınızı temsil eden kendi karşılaştırmalarınızı yapın.
Uygulama
Uygulamamızdaki temel adımlar şunlardır:
Zararlılık eşiği belirleme
Zararlılık sınıflandırıcımız, 0 ile 1 arasında zararlılık puanları sağlar. Bu aralıkta, neyin zararlı yorum olarak kabul edileceğini belirlemek için bir eşik belirlememiz gerekir. Yaygın olarak kullanılan eşik 0.9'dır. Bu sayede, aşırı hassasiyetten kaçınarak (bu durum, çok fazla yanlış pozitif sonuca yani zararsız yorumların toksik olarak sınıflandırılmasına yol açabilir) açıkça toksik yorumları yakalayabilirsiniz.
export const TOXICITY_THRESHOLD = 0.9
Bileşenleri içe aktarma
@xenova/transformers kitaplığından gerekli bileşenleri içe aktararak başlıyoruz. Ayrıca, toksisite eşiğimiz de dahil olmak üzere sabitleri ve yapılandırma değerlerini de içe aktarırız.
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';
Modeli yükleme ve ana iş parçacığıyla iletişim kurma
Kötü niyetli davranış algılama modeli toxic-bert'ü yükleyip sınıflandırıcıyı hazırlamak için kullanırız. Bunun en az karmaşık sürümü const classifier = await pipeline('text-classification', MODEL_NAME);
Örnek koddaki gibi bir işlem hattı oluşturmak, çıkarım görevlerini çalıştırmanın ilk adımıdır.
Pipeline işlevi iki bağımsız değişken alır: görev ('text-classification') ve model (Xenova/toxic-bert).
Önemli terim: Transformers.js'de ardışık düzen, makine öğrenimi modellerini çalıştırma sürecini basitleştiren üst düzey bir API'dir. Model yükleme, belirteçleştirme ve işleme sonrası gibi görevleri yönetir.
Hesaplama açısından maliyetli olan model hazırlama adımlarını bir web çalışanı üzerinden gerçekleştirdiğimiz için demo kodumuz, modeli hazırlamaktan biraz daha fazlasını yapar. Bu sayede ana ileti dizisi yanıt vermeye devam edebilir. Maliyetli görevleri web worker'a aktarma hakkında daha fazla bilgi edinin.
Çalışanımızın, modelin durumunu ve uygunsuzluk değerlendirmesinin sonuçlarını belirtmek için mesajları kullanarak ana iş parçacığıyla iletişim kurması gerekir. Model hazırlama ve çıkarım yaşam döngüsünün farklı durumlarıyla eşleşen mesaj kodlarımıza göz atın.
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 });
}
})();
Kullanıcı girişini sınıflandırma
classify işlevimizde, kullanıcı yorumunu analiz etmek için daha önce oluşturduğumuz sınıflandırıcıyı kullanıyoruz. Kötüye kullanım sınıflandırıcısının ham çıkışını (etiketler ve puanlar) döndürürüz.
// 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;
}
Ana ileti dizisi, çalışandan bunu yapmasını istediğinde sınıflandırma işlevimizi çağırırız.
Demomuzda, kullanıcı yazmayı bıraktığı anda sınıflandırıcıyı tetikleriz
(TYPING_DELAY bölümüne bakın). Bu durumda, ana ileti dizimiz çalışana sınıflandırılacak kullanıcı girişini içeren bir mesaj gönderir.
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,
});
};
Çıkışı işleme
Sınıflandırıcının çıkış puanlarının eşiğimizi aşıp aşmadığını kontrol ederiz. Bu durumda söz konusu etiketi not ederiz.
Kötüye kullanım etiketlerinden herhangi biri listeleniyorsa yorum, kötüye kullanım amaçlı olma ihtimali olan yorum olarak işaretlenir.
// 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,
});
};
İpucu görüntüleme
isToxic doğruysa kullanıcıya bir ipucu gösteririz. Demomuzda daha ayrıntılı toksisite türünü kullanmıyoruz ancak gerekirse ana iş parçacığında kullanılabilir hale getirdik (toxicityTypeList). Bu tür, kullanım alanınız için faydalı olabilir.
Kullanıcı deneyimi
Demomuzda aşağıdaki seçimleri yaptık:
- Her zaman yayınlamaya izin ver İstemci tarafındaki zararlılık ipucumuz, kullanıcının yayınlamasını engellemez. Demomuzda kullanıcı, model yüklenmemiş olsa (bu nedenle toksisite değerlendirmesi sunmuyor olsa) ve yorum toksik olarak algılansa bile yorum gönderebiliyor. Önerildiği gibi, zararlı yorumları tespit etmek için ikinci bir sisteminiz olmalıdır. Uygulamanız için uygunsa kullanıcıyı, yorumunun istemcide gönderildiğini ancak sunucuda veya insan incelemesi sırasında işaretlendiği konusunda bilgilendirebilirsiniz.
- Yanlış negatiflere dikkat edin. Bir yorum zararlı olarak sınıflandırılmadığında demomuz geri bildirim sağlamaz (ör. "Güzel yorum!"). Olumlu geri bildirimler, gürültülü olmanın yanı sıra yanlış sinyal de gönderebilir. Çünkü sınıflandırıcımız, zaman zaman ancak kaçınılmaz olarak bazı zararlı yorumları gözden kaçırır.
Geliştirmeler ve alternatifler
Sınırlamalar ve gelecekte yapılacak geliştirmeler
- Diller: Kullandığımız model öncelikle İngilizceyi destekler. Çok dilli destek için ince ayar yapmanız gerekir. Hugging Face'te listelenen birden fazla zararlılık modeli, şu anda Transformers.js ile uyumlu olmasa da İngilizce dışındaki dilleri (Rusça, Felemenkçe) desteklemektedir.
- İnce anlamlar: Toxic-bert, açıkça görülen toksik içerikleri etkili bir şekilde tespit etse de daha ince veya bağlama bağlı durumlarda (ör. ironi, alay) zorlanabilir. Zararlı içerik, son derece öznel ve ince bir konu olabilir. Örneğin, belirli terimlerin veya emojilerin zararlı olarak sınıflandırılmasını isteyebilirsiniz. İnce ayar, bu alanlardaki doğruluğu artırmaya yardımcı olabilir.
Yakında, toksisite modeline ince ayar yapma hakkında bir makale yayınlayacağız.
Alternatifler
- Metin sınıflandırma için MediaPipe. Sınıflandırma görevleriyle uyumlu bir model kullandığınızdan emin olun.
TensorFlow.js toxicity classifier. Bu model daha küçüktür ve daha hızlı getirilir ancak bir süredir optimize edilmediği için çıkarımın Transformers.js'e kıyasla biraz daha yavaş olduğunu fark edebilirsiniz.
Sonuç
İstemci tarafında zararlı içerik algılama, online toplulukları geliştirmek için kullanabileceğiniz güçlü bir araçtır.
Transformers.js ile tarayıcıda çalışan toxic-bert gibi yapay zeka modellerinden yararlanarak, zararlı davranışları engelleyen ve sunucularınızdaki zararlılık sınıflandırma yükünü azaltan anlık geri bildirim mekanizmaları uygulayabilirsiniz.
Bu istemci taraflı yaklaşım, tarayıcılar arasında zaten çalışmaktadır. Ancak özellikle model sunma maliyetleri ve indirme boyutu açısından sınırlamaları göz önünde bulundurun. İstemci tarafı yapay zeka için performansla ilgili en iyi uygulamaları uygulayın ve modeli önbelleğe alın.
Kapsamlı toksisite algılama için istemci tarafı ve sunucu tarafı yaklaşımlarını birleştirin.