يغطي هذا الموضوع إعداد ميزة NSFW (غير آمن للعمل) الخاصة بمكون Discourse AI الإضافي.
مستوى المستخدم المطلوب: مسؤول
يمكن لوحدات NSFW تصنيف درجة NSFW تلقائيًا لكل تحميل صورة جديد في المنشورات ورسائل الدردشة في مثيل Discourse الخاص بك. يساعد هذا النظام في تحديد وإدارة المحتوى الذي قد يكون غير مناسب أو صريحًا لبيئة احترافية أو عامة.
يمكنك أيضًا تمكين وضع علامة تلقائية على المحتوى الذي يتجاوز عتبة معينة.
الإعدادات
ai_nsfw_detection_enabled: تمكين أو تعطيل الوحدة.
ai_nsfw_inference_service_api_endpoint: عنوان URL حيث تعمل واجهة برمجة التطبيقات (API) للوحدة. إذا كنت تستخدم استضافة CDCK، فسيتم التعامل مع هذا تلقائيًا. إذا كنت تستضيف بنفسك، تحقق من دليل الاستضافة الذاتية.
ai_nsfw_inference_service_api_key: مفتاح API لواجهة برمجة التطبيقات (API) المكونة أعلاه. إذا كنت تستخدم استضافة CDCK، فسيتم التعامل مع هذا تلقائيًا. إذا كنت تستضيف بنفسك، تحقق من دليل الاستضافة الذاتية.
ai_nsfw_models: النموذج الذي سنستخدمه لتصنيف الصور. نقدم نموذجين مختلفين مع عتباتهما:
- opennsfw2 يُرجع درجة واحدة بين
0.0و1.0. قم بتعيين العتبة لاعتبار التحميل غير آمن للعمل (NSFW) من خلال إعدادai_nsfw_flag_threshold_general.- nsfw_detector يُرجع درجات لأربع فئات:
drawings(رسومات)،hentai(هينتاي)،porn(مواد إباحية)، وsexy(مثير). قم بتعيين العتبة لكل منها من خلال إعدادai_nsfw_flag_threshold_${category}الخاص بها. إذا كانت العتبة العامة أقل من أي من هذه، فسنعتبر المحتوى غير آمن للعمل (NSFW).ai_nsfw_flag_automatically: وضع علامة تلقائية على المنشورات/رسائل الدردشة التي تتجاوز العتبات المكونة. عندما يتم تعطيل هذا الإعداد، نقوم فقط بتخزين نتائج التصنيف في قاعدة البيانات.
موارد إضافية
شكرا.
وجدت هذه المشكلة عند استخدام خدمة nsfw، بعد تحميل صورة. أستخدم S3 لتخزين الصور، إذا كان هذا ذا صلة.
INFO: 10.0.2.145:23412 - "POST /api/v1/classify HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/anyio/streams/memory.py", line 94, in receive
return self.receive_nowait()
File "/usr/local/lib/python3.9/dist-packages/anyio/streams/memory.py", line 89, in receive_nowait
raise WouldBlock
anyio.WouldBlock
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/base.py", line 77, in call_next
message = await recv_stream.receive()
File "/usr/local/lib/python3.9/dist-packages/anyio/streams/memory.py", line 114, in receive
raise EndOfStream
anyio.EndOfStream
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/uvicorn/protocols/http/h11_impl.py", line 404, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "/usr/local/lib/python3.9/dist-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/dist-packages/starlette/applications.py", line 124, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/errors.py", line 184, in __call__
raise exc
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.9/dist-packages/starlette_exporter/middleware.py", line 289, in __call__
await self.app(scope, receive, wrapped_send)
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/cors.py", line 84, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/base.py", line 106, in __call__
response = await self.dispatch_func(request, call_next)
File "./app.py", line 49, in dispatch
response = await call_next(request)
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/base.py", line 80, in call_next
raise app_exc
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/base.py", line 69, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/exceptions.py", line 79, in __call__
raise exc
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/exceptions.py", line 68, in __call__
await self.app(scope, receive, sender)
File "/usr/local/lib/python3.9/dist-packages/starlette/routing.py", line 706, in __call__
await route.handle(scope, receive, send)
File "/usr/local/lib/python3.9/dist-packages/starlette/routing.py", line 276, in handle
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/dist-packages/starlette/routing.py", line 66, in app
response = await func(request)
File "./app.py", line 79, in classify
results = models[parsed_params.model](tfile)
File "/usr/local/lib/python3.9/dist-packages/opennsfw2/_inference.py", line 31, in predict_image
pil_image = Image.open(image_path)
File "/usr/local/lib/python3.9/dist-packages/PIL/Image.py", line 3283, in open
raise UnidentifiedImageError(msg)
PIL.UnidentifiedImageError: cannot identify image file '/tmp/tmpbqq82655'
ERROR:uvicorn.error:Exception in ASGI application
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/anyio/streams/memory.py", line 94, in receive
return self.receive_nowait()
File "/usr/local/lib/python3.9/dist-packages/anyio/streams/memory.py", line 89, in receive_nowait
raise WouldBlock
anyio.WouldBlock
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/base.py", line 77, in call_next
message = await recv_stream.receive()
File "/usr/local/lib/python3.9/dist-packages/anyio/streams/memory.py", line 114, in receive
raise EndOfStream
anyio.EndOfStream
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/dist-packages/uvicorn/protocols/http/h11_impl.py", line 404, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "/usr/local/lib/python3.9/dist-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/dist-packages/starlette/applications.py", line 124, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/errors.py", line 184, in __call__
raise exc
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.9/dist-packages/starlette_exporter/middleware.py", line 289, in __call__
await self.app(scope, receive, wrapped_send)
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/cors.py", line 84, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/base.py", line 106, in __call__
response = await self.dispatch_func(request, call_next)
File "./app.py", line 49, in dispatch
response = await call_next(request)
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/base.py", line 80, in call_next
raise app_exc
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/base.py", line 69, in coro
await self.app(scope, receive_or_disconnect, send_no_error)
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/exceptions.py", line 79, in __call__
raise exc
File "/usr/local/lib/python3.9/dist-packages/starlette/middleware/exceptions.py", line 68, in __call__
await self.app(scope, receive, sender)
File "/usr/local/lib/python3.9/dist-packages/starlette/routing.py", line 706, in __call__
await route.handle(scope, receive, send)
File "/usr/local/lib/python3.9/dist-packages/starlette/routing.py", line 276, in handle
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/dist-packages/starlette/routing.py", line 66, in app
response = await func(request)
File "./app.py", line 79, in classify
results = models[parsed_params.model](tfile)
File "/usr/local/lib/python3.9/dist-packages/opennsfw2/_inference.py", line 31, in predict_image
pil_image = Image.open(image_path)
File "/usr/local/lib/python3.9/dist-packages/PIL/Image.py", line 3283, in open
raise UnidentifiedImageError(msg)
PIL.UnidentifiedImageError: cannot identify image file '/tmp/tmpbqq82655'
في Sidekiq يبدو الأمر هكذا:
ماذا أفعل بشكل خاطئ؟
أعتقد أن هذا قد يكون متعلقًا بـ S3 حقًا. عند تحميل صورة، تُظهر سجلات الأخطاء هذه الأخطاء:
URL إلى S3 تم حذفه…
لذلك يبدو أن المكون الإضافي يحاول تحميل الصورة مبكرًا جدًا أو لا يجده لأسباب أخرى.
لقد اختبرته فقط مع المواقع التي تستخدم شبكة توصيل محتوى (CDN) لـ S3 أو تستخدم التخزين المحلي. إذا كنت تستخدم تخزين الكائنات (Object Storage)، فإنني أنصح باستخدام شبكة توصيل محتوى (CDN) لتكون واجهته.
هذا بالضبط ما نفعله - AWS Cloudfront. المكدس يعتمد على GitHub - aws-samples/aws-cdk-for-discourse: AWS CDK for Discourse. سأحاول تصحيح الأخطاء ونشر النتائج.
من أين أحصل على مفتاح واجهة برمجة التطبيقات (API) الخاص به؟
يجب أن يكون تحت لوحة المسؤول، أليس كذلك؟
يبدو أن هذا حساس للغاية بالنسبة لي، فهو يضع علامات على الأشياء كثيرًا جدًا. مجرد صور الأشخاص يتم تمييزها على أنها NSFW.
لدي العتبات عند 60. ليس من الواضح ما إذا كان يجب علي زيادة هذا الرقم أو تقليله، وما هو الحد؟ إذا قمت بتعيينه على 100، فهل هذا يعطلها بشكل أساسي؟ لا يبدو أن هناك الكثير من الوثائق حول هذا الموضوع.
أيضًا، لماذا لا توجد طريقة لتعطيله تمامًا لأدوار معينة، كما هو الحال مع السمية؟ أنا متأكد من أن أعضاء فريق العمل لدينا لن ينشروا أي شيء فظ، ومع ذلك فهم يقاتلون باستمرار مع الذكاء الاصطناعي لأنه يميز أشياءهم. لقد أصبح الأمر بمثابة مزحة في منتدىي.
باستخدام opennsfw2.
للأسف، تفتقر نماذج التعلم الآلي القديمة هذه إلى المرونة، وبينما أنها سهلة من حيث متطلبات تشغيل نسختك الخاصة، وجدنا أن الصرامة كانت عقبة كبيرة أمام مجموعة متنوعة من المجتمعات التي تستخدم Discourse.
حاليًا، تتمثل خطتنا في إيقاف جميع الميزات التي تعتمد على هذه النماذج القديمة وترحيل كل شيء إلى نماذج لغوية كبيرة حديثة، حيث ستتمكن من تعديل المطالبة لتناسب احتياجاتك بشكل أفضل.
هل كان هناك أي تغيير في هذا على الإطلاق؟ لا يزال كاشف المحتوى غير اللائق (NSFW) غير دقيق بشكل كبير، ويتم تفعيله على معظم الصور التي تحتوي على أشخاص.
نعم، لقد قمنا بتوصيل خطتنا في ما هو التالي للكشف عن المحتوى غير الآمن في Discourse AI، ولكن الملخص هو أنه يمكنك استخدام مصنف منشورات Discourse AI - قاعدة الأتمتة لدقة ومرونة أفضل بكثير.
لقد أجرينا تقييمات لحالة استخدام المحتوى غير الآمن عبر نماذج الرؤية اللغوية الكبيرة وحصلنا على نتائج رائعة، لذلك نقوم حاليًا بطرح هذا لعملائنا من الشركات وسننشر أدلتنا حول هذا الموضوع في الأسابيع القادمة.

