Discourse AI - NSFW

:bookmark: يغطي هذا الموضوع إعداد ميزة NSFW (غير آمن للعمل) الخاصة بمكون Discourse AI الإضافي.

:person_raising_hand: مستوى المستخدم المطلوب: مسؤول

يمكن لوحدات 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: وضع علامة تلقائية على المنشورات/رسائل الدردشة التي تتجاوز العتبات المكونة. عندما يتم تعطيل هذا الإعداد، نقوم فقط بتخزين نتائج التصنيف في قاعدة البيانات.

موارد إضافية

11 إعجابًا

شكرا.
وجدت هذه المشكلة عند استخدام خدمة 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) لتكون واجهته.

إعجاب واحد (1)

هذا بالضبط ما نفعله - AWS Cloudfront. المكدس يعتمد على GitHub - aws-samples/aws-cdk-for-discourse: AWS CDK for Discourse. سأحاول تصحيح الأخطاء ونشر النتائج.

إعجابَين (2)

من أين أحصل على مفتاح واجهة برمجة التطبيقات (API) الخاص به؟

يجب أن يكون تحت لوحة المسؤول، أليس كذلك؟

يبدو أن هذا حساس للغاية بالنسبة لي، فهو يضع علامات على الأشياء كثيرًا جدًا. مجرد صور الأشخاص يتم تمييزها على أنها NSFW.

لدي العتبات عند 60. ليس من الواضح ما إذا كان يجب علي زيادة هذا الرقم أو تقليله، وما هو الحد؟ إذا قمت بتعيينه على 100، فهل هذا يعطلها بشكل أساسي؟ لا يبدو أن هناك الكثير من الوثائق حول هذا الموضوع.

أيضًا، لماذا لا توجد طريقة لتعطيله تمامًا لأدوار معينة، كما هو الحال مع السمية؟ أنا متأكد من أن أعضاء فريق العمل لدينا لن ينشروا أي شيء فظ، ومع ذلك فهم يقاتلون باستمرار مع الذكاء الاصطناعي لأنه يميز أشياءهم. لقد أصبح الأمر بمثابة مزحة في منتدىي.

باستخدام opennsfw2.

إعجاب واحد (1)

للأسف، تفتقر نماذج التعلم الآلي القديمة هذه إلى المرونة، وبينما أنها سهلة من حيث متطلبات تشغيل نسختك الخاصة، وجدنا أن الصرامة كانت عقبة كبيرة أمام مجموعة متنوعة من المجتمعات التي تستخدم Discourse.

حاليًا، تتمثل خطتنا في إيقاف جميع الميزات التي تعتمد على هذه النماذج القديمة وترحيل كل شيء إلى نماذج لغوية كبيرة حديثة، حيث ستتمكن من تعديل المطالبة لتناسب احتياجاتك بشكل أفضل.

إعجاب واحد (1)

هل كان هناك أي تغيير في هذا على الإطلاق؟ لا يزال كاشف المحتوى غير اللائق (NSFW) غير دقيق بشكل كبير، ويتم تفعيله على معظم الصور التي تحتوي على أشخاص.

نعم، لقد قمنا بتوصيل خطتنا في ما هو التالي للكشف عن المحتوى غير الآمن في Discourse AI، ولكن الملخص هو أنه يمكنك استخدام مصنف منشورات Discourse AI - قاعدة الأتمتة لدقة ومرونة أفضل بكثير.

لقد أجرينا تقييمات لحالة استخدام المحتوى غير الآمن عبر نماذج الرؤية اللغوية الكبيرة وحصلنا على نتائج رائعة، لذلك نقوم حاليًا بطرح هذا لعملائنا من الشركات وسننشر أدلتنا حول هذا الموضوع في الأسابيع القادمة.

إعجابَين (2)