Verarbeiten – chatgpz.de – KI-Tools & Praxiswissen http://chatgpz.de Unabhängige Tests, Anleitungen und Hintergründe zu KI-Tools. Sat, 11 Jul 2026 11:09:32 +0000 de-DE hourly 1 https://wordpress.org/?v=6.4.2 234900186 Lokale Videozusammenfassungspipeline: Frames mit SmolVLM2-2.2B verarbeiten http://chatgpz.de/data-analytics/lokale-videozusammenfassungspipeline-frames-mit-smolvlm2-2-2b-verarbeiten/ http://chatgpz.de/data-analytics/lokale-videozusammenfassungspipeline-frames-mit-smolvlm2-2-2b-verarbeiten/#respond Sat, 11 Jul 2026 11:09:32 +0000 https://chatgpz.de/data-analytics/lokale-videozusammenfassungspipeline-frames-mit-smolvlm2-2-2b-verarbeiten/ [ad_1]

Lokale Videozusammenfassungspipeline: Frames mit SmolVLM2-2.2B verarbeiten

# Einführung

Die meisten Instruments zum Verstehen von Movies fallen in eines von zwei Lagern. Das erste Camp erfordert eine Cloud-API; Ihr Filmmaterial wird hochgeladen, auf den Servern einer anderen Particular person verarbeitet und professional Videominute abgerechnet. Das zweite Lager läuft lokal, erfordert aber die Artwork von GPU-Cluster, über die die meisten Entwickler nicht verfügen: 70B+-Modelle, die mehrere A100 benötigen und Minuten professional Clip benötigen. Keine der beiden Optionen funktioniert für einen Entwickler, der Besprechungsaufzeichnungen, eine Vortragsreihe oder Sicherheitsaufnahmen eines Tages auf einer Workstation verarbeiten möchte, die er bereits besitzt.

SmolVLM2-2.2B-Anleitungveröffentlicht von Umarmendes Gesicht am 20. Februar 2025 ändert die Berechnung. Es läuft auf 5,2 GB GPU-RAM, einer RTX 3060, einem MacBook Professional M2 und dem kostenlosen Google Colab T4-Stufe. An Video-MMEdem Commonplace-Benchmark für das Videoverständnis im Langformat, übertrifft es jedes vorhandene Modell im 2B-Maßstab. Diese Kombination aus Client-{Hardware} gepaart mit Ergebnissen, die tatsächlich Bestand haben, ist das, worum es in diesem Artikel geht.

Das Projekt, das wir in diesem Artikel erstellen werden: eine lokale Pipeline, die jede Videodatei aufnimmt, Frames in konfigurierbaren Intervallen extrahiert, sie stapelweise mit SmolVLM2-2.2B analysiert und eine strukturierte JSON-Zusammenfassung ausgibt, einschließlich Szenenbeschreibungen professional Body, Schlüsselmomenten mit Zeitstempeln, Aktionselementen und einer abschließenden Erzählung. Die gleiche Pipeline verarbeitet Besprechungsaufzeichnungen, Vorträge und Überwachungsaufnahmen, ohne eine Codezeile zu ändern.

# SmolVLM2-2.2B

Der Grund, warum SmolVLM2-2.2B auf einer RTX 3060 laufen kann und dabei größere Modelle bei Videoaufgaben übertrifft, ist eine Designentscheidung darüber, wie Bilder tokenisiert werden.

Die meisten Imaginative and prescient-Language-Modelle tokenisieren Bilder mit hoher Dichte. Qwen2-VLverwendet beispielsweise bis zu 16.000 Token, um ein einzelnes Bild darzustellen. Die Einspeisung von 50 Frames in ein solches Modell mit dieser Dichte würde 800.000 Token verbrauchen, was weit über das Kontextbudget einer Client-GPU hinausgeht. SmolVLM2 verwendet a Pixel-Shuffle-Strategie Dadurch wird jeder 384×384-Bild-Patch auf 81 Token komprimiert. Aus fünfzig Bildern werden ungefähr 4.050 Bildtokens, die in einem einzigen Inferenzaufruf verwaltet werden können. Diese Komprimierung ist der Grund Der Vorfülldurchsatz von SmolVLM2 ist 3,3- bis 4,5-mal schneller und der Generierungsdurchsatz 7,5- bis 16-mal schneller als bei Qwen2-VL-2Bnicht als Marketingaussage, sondern als direkte Folge der symbolischen Budgetdifferenz.

Das Modell ist in drei Größen erhältlich. Die Varianten 256M und 500M sind für Mobil- und Edge-Geräte konzipiert; Der 256M kann auf einem Telefon ausgeführt werden. Für diese Pipeline ist der 2.2B die richtige Wahl. Es ist die einzige Größe mit ausreichend starken Video-Benchmark-Ergebnissen, um zuverlässige Multiszenen-Zusammenfassungen zu erstellen: Video-MME von 52,1, MLVU von 55,2 und MVBench von 46,27 im Vergleich zu 42,2, 47,3 bzw. 39,73 des 500M.

Es lohnt sich auch, den Videoverständnisansatz zu verstehen, bevor Sie Code schreiben. SmolVLM2 verfügt nicht über einen nativen Video-Encoder; Es behandelt Movies als eine Folge von Bildern. Der offizielle Referenzpipeline Extrahiert bis zu 50 gleichmäßig abgetastete Bilder professional Video, umgeht die interne Größenänderung der Bilder und übergibt sie als Mehrbildsequenz in einer einzelnen Chat-Nachricht. Dieser Ansatz erreichte 27,14 % CinePileund positionierte es zwischen InternVL2 (2B) und Video-LLaVA (7B) hinsichtlich des filmischen Videoverständnisses. Angesichts der Größe des Modells battle dies ein starkes Ergebnis, und Video battle nicht das Einzige, wofür es trainiert wurde.

# Einrichten der Umgebung

Hardwareanforderungen:

Besonderheit Minimal Empfohlen
GPU-VRAM 6 GB (RTX 3060) 12–16 GB (RTX 4080)
Apple Silicon M2 8 GB (MPS-Pfad) M2 Professional / M3 16 GB
System-RAM 16 GB 32 GB
Scheibe 10 GB kostenlos 20 GB+ SSD
Colab T4 (kostenloses Kontingent) A100 (Colab Professional)

Python-Pakete:

# Python 3.10+ required
python --version

python -m venv smolvlm2-env
supply smolvlm2-env/bin/activate       # macOS / Linux
smolvlm2-envScriptsactivate          # Home windows

# Set up from the secure SmolVLM-2 department -- required for SmolVLM2 assist
pip set up git+https://github.com/huggingface/transformers@v4.49.0-SmolVLM-2

# Core dependencies
pip set up torch torchvision --index-url https://obtain.pytorch.org/whl/cu121
pip set up 
  opencv-python 
  Pillow 
  numpy 
  num2words 
  speed up

# Flash Consideration 2 for CUDA -- considerably quicker on NVIDIA GPUs
# Skip this on Apple Silicon and CPU -- it's CUDA-only
pip set up flash-attn --no-build-isolation

# decord -- required for SmolVLM2's native video enter path (utilized in Part 5)
pip set up decord

Notiz: Der num2words Paket ist eine nicht offensichtliche Abhängigkeit. Der Prozessor von SmolVLM2 verwendet es, um numerische Ziffern in Wortdarstellungen (z. B. 3 → „drei“) umzuwandeln, um die Konsistenz mit Trainingsmustern natürlicher Sprache zu gewährleisten, z wird in dieser Komplettlösung erklärt. Wenn Sie es weglassen, kommt es beim Laden des Prozessors zu einem Fehler beim stillen Import.

Geräteprüfung (führen Sie diese vor dem Laden des Modells durch):

# device_check.py
# Run: python device_check.py

import torch

def detect_device():
    if torch.cuda.is_available():
        title  = torch.cuda.get_device_name(0)
        vram  = torch.cuda.get_device_properties(0).total_memory / 1e9
        print(f"CUDA: {title} ({vram:.1f} GB VRAM)")
        return "cuda", torch.bfloat16, "flash_attention_2"
    elif hasattr(torch.backends, "mps") and torch.backends.mps.is_available():
        print("Apple Silicon MPS detected")
        return "mps", torch.float16, "keen"
    else:
        print("CPU fallback (sluggish -- take into account Colab T4)")
        return "cpu", torch.float32, "keen"

if __name__ == "__main__":
    system, dtype, attn = detect_device()
    print(f"Machine: {system} | dtype: {dtype} | attn: {attn}")

Führen Sie es aus mit:

# Aufbau des Fundaments der Pipeline

Bevor SmolVLM2 etwas sieht, benötigen Sie Frames. Der Body-Extraktor konvertiert eine Videodatei in eine Liste von PIL (Python Imaging Library) Bilder mit angehängten Zeitstempeln, ein Paar professional extrahiertem Body.

Für unterschiedliche Anwendungsfälle sind zwei Modi von Bedeutung. Durch das einheitliche Sampling werden die Bilder gleichmäßig über die gesamte Videodauer verteilt, sodass unabhängig vom Inhalt alles abgedeckt wird. Dies ist die richtige Wahl für Besprechungen und Vorträge, bei denen Sie es sich nicht leisten können, einen Abschnitt zu verpassen. Beim Keyframe-Sampling werden nur Bilder extrahiert, bei denen sich der visuelle Inhalt erheblich ändert, z. B. bei Szenenschnitten, einer neuen Folie oder einem neuen Sprecher. Dadurch wird die Anzahl der Bilder reduziert und die Aufmerksamkeit auf bestimmte Momente gelenkt. Dies ist besser für die Überwachung und Spotlight-Extraktion.

# frame_extractor.py
# Conditions: pip set up opencv-python Pillow numpy
# Utilization: from frame_extractor import FrameExtractor

import cv2
import numpy as np
from PIL import Picture


class FrameExtractor:
    """
    Extracts video frames as PIL Photographs for SmolVLM2 inference.
    Every extracted body is paired with its timestamp in seconds.

    SmolVLM2 makes use of ~81 visible tokens per picture. At 50 frames that's
    roughly 4,050 picture tokens -- the sensible higher restrict earlier than VRAM
    strain impacts era high quality on client GPUs.
    """

    MAX_FRAMES = 50

    def __init__(self, max_frames: int = MAX_FRAMES):
        """
        Args:
            max_frames: Exhausting cap on extracted frames. Default 50 matches
                        the SmolVLM2 reference pipeline's examined higher restrict.
        """
        self.max_frames = max_frames

    def uniform_sample(self, video_path: str) -> listing(tuple(float, Picture.Picture)):
        """
        Extract evenly spaced frames throughout the complete video period.
        Finest for: assembly recordings, lectures, tutorials, course content material.

        Returns:
            Listing of (timestamp_seconds, PIL_Image) in chronological order.
        """
        cap = cv2.VideoCapture(video_path)
        if not cap.isOpened():
            elevate IOError(f"Can't open video: {video_path}")

        total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
        fps          = cap.get(cv2.CAP_PROP_FPS) or 30.0
        n_extract    = min(self.max_frames, total_frames)

        # Construct body indices unfold evenly from first to final body
        indices = np.linspace(0, total_frames - 1, n_extract, dtype=int)
        outcomes = ()

        for idx in indices:
            cap.set(cv2.CAP_PROP_POS_FRAMES, int(idx))
            ret, body = cap.learn()
            if not ret:
                proceed
            timestamp = spherical(idx / fps, 2)
            rgb = cv2.cvtColor(body, cv2.COLOR_BGR2RGB)
            outcomes.append((timestamp, Picture.fromarray(rgb)))

        cap.launch()
        return outcomes

    def keyframe_sample(
        self, video_path: str, diff_threshold: float = 30.0
    ) -> listing(tuple(float, Picture.Picture)):
        """
        Extract frames the place visible content material adjustments considerably.
        Finest for: surveillance, occasion detection, spotlight extraction.

        Makes use of imply absolute pixel distinction between consecutive grayscale frames
        because the change sign. When the diff exceeds diff_threshold, a brand new
        keyframe is recorded.

        Args:
            diff_threshold: Imply pixel distinction to deal with as a scene change.
                            30.0 works for many industrial content material.
                            Decrease = extra delicate, greater = fewer frames.

        Returns:
            Listing of (timestamp_seconds, PIL_Image) in chronological order,
            capped at self.max_frames.
        """
        cap = cv2.VideoCapture(video_path)
        if not cap.isOpened():
            elevate IOError(f"Can't open video: {video_path}")

        fps       = cap.get(cv2.CAP_PROP_FPS) or 30.0
        outcomes   = ()
        prev_gray = None
        idx       = 0

        whereas len(outcomes) < self.max_frames:
            ret, body = cap.learn()
            if not ret:
                break

            grey = cv2.cvtColor(body, cv2.COLOR_BGR2GRAY)

            if prev_gray is None:
                # All the time seize the primary body as a baseline
                rgb = cv2.cvtColor(body, cv2.COLOR_BGR2RGB)
                outcomes.append((spherical(idx / fps, 2), Picture.fromarray(rgb)))
            else:
                diff = np.imply(np.abs(grey.astype(float) - prev_gray.astype(float)))
                if diff > diff_threshold:
                    rgb = cv2.cvtColor(body, cv2.COLOR_BGR2RGB)
                    outcomes.append((spherical(idx / fps, 2), Picture.fromarray(rgb)))

            prev_gray = grey
            idx += 1

        cap.launch()
        return outcomes

Beginnen Sie jeden neuen Videotyp mit uniform_sample. Wenn Sie zu viele redundante Bilder finden (fünf nahezu identische Folien hintereinander), wechseln Sie zu keyframe_sample und stimmen diff_threshold von 30 auf 20 herunter, bis sich die extrahierte Menge repräsentativ anfühlt, ohne überflüssig zu sein.

# Laden von SmolVLM2 und Ausführen von Single-Body-Inferenz

Mit den vorliegenden Frames finden Sie hier das vollständige Modelllade- und Erstinferenzmuster. Die wichtigen Particulars: AutoModelForImageTextToText ist die richtige Klasse (nicht die generische). AutoModelForCausalLM), und auf CUDA sollten Sie es aktivieren Blitzaufmerksamkeit 2was bedeutende Latenzverbesserungen bei Eingaben mit mehreren Bildern bietet.

# smolvlm2_loader.py
# Conditions: transformers from v4.49.0-SmolVLM-2 department, torch, flash-attn (CUDA solely)
# Run: python smolvlm2_loader.py your_video.mp4

import sys
import torch
from PIL import Picture
from transformers import AutoProcessor, AutoModelForImageTextToText

MODEL_ID = "HuggingFaceTB/SmolVLM2-2.2B-Instruct"


def load_model():
    """
    Load SmolVLM2-2.2B and its processor.
    Robotically selects Flash Consideration 2 on CUDA, keen mode elsewhere.
    First run downloads ~4.5 GB of weights to ~/.cache/huggingface/hub.
    """
    if torch.cuda.is_available():
        dtype  = torch.bfloat16
        system = "cuda"
        attn   = "flash_attention_2"
    elif hasattr(torch.backends, "mps") and torch.backends.mps.is_available():
        dtype  = torch.float16
        system = "mps"
        attn   = "keen"
    else:
        dtype  = torch.float32
        system = "cpu"
        attn   = "keen"

    print(f"Loading {MODEL_ID} on {system}...")

    processor = AutoProcessor.from_pretrained(MODEL_ID)

    mannequin = AutoModelForImageTextToText.from_pretrained(
        MODEL_ID,
        torch_dtype=dtype,
        _attn_implementation=attn,
    ).to(system)

    mannequin.eval()
    print(f"Mannequin prepared on {system}")
    return mannequin, processor


def describe_frame(
    mannequin,
    processor,
    body: Picture.Picture,
    immediate: str = "Describe what is going on on this body intimately. Be aware any textual content, folks, objects, or actions seen.",
    max_new_tokens: int = 256,
) -> str:
    """
    Run SmolVLM2 inference on a single PIL Picture.

    The chat template expects picture content material earlier than textual content content material within the
    message -- this mirrors the coaching knowledge format and is essential
    for dependable output.

    Args:
        body:          A PIL Picture (from FrameExtractor)
        immediate:         What to ask the mannequin about this body
        max_new_tokens: Most response size in tokens

    Returns:
        Mannequin response as a plain string
    """
    messages = (
        {
            "position": "person",
            "content material": (
                # Picture positioned earlier than textual content -- matches SmolVLM2 coaching format
                {"kind": "picture"},
                {"kind": "textual content", "textual content": immediate},
            ),
        }
    )

    # apply_chat_template codecs the message and injects visible token placeholders
    input_text = processor.apply_chat_template(
        messages,
        add_generation_prompt=True,
    )

    inputs = processor(
        photos=(body),
        textual content=input_text,
        return_tensors="pt",
    ).to(mannequin.system)

    with torch.no_grad():
        output_ids = mannequin.generate(
            **inputs,
            max_new_tokens=max_new_tokens,
            do_sample=False,   # Grasping decoding for constant structured output
        )

    # Decode solely the newly generated tokens -- strip the enter immediate
    new_tokens = output_ids(0)(inputs("input_ids").form(-1):)
    return processor.decode(new_tokens, skip_special_tokens=True).strip()


# ── Fast sanity test ────────────────────────────────────────────────────────

if __name__ == "__main__":
    from frame_extractor import FrameExtractor

    if len(sys.argv) < 2:
        print("Utilization: python smolvlm2_loader.py ")
        sys.exit(1)

    mannequin, processor = load_model()
    extractor = FrameExtractor(max_frames=5)

    frames = extractor.uniform_sample(sys.argv(1))
    ts, first_frame = frames(0)

    print(f"nDescribing body at {ts}s...")
    description = describe_frame(mannequin, processor, first_frame)
    print(f"n{description}")

So führen Sie aus:

python smolvlm2_loader.py your_video.mp4

Die Beschreibung, die Sie zurückerhalten, ist Ihr Gesundheitscheck. Wenn das Modell sichtbaren Textual content, Personen, Objekte und Aktionen im ersten Body korrekt identifiziert, funktioniert die Pipeline. Wenn Sie eine sehr kurze oder offensichtlich falsche Antwort erhalten, überprüfen Sie, ob die transformers Model ist von der v4.49.0-SmolVLM-2 Zweig; Die stabile Hugging Face-Model beinhaltet zum Zeitpunkt des Schreibens noch keine SmolVLM2-Unterstützung.

# Aufbau des Actual-World-Projekts (Assembly Recording Summarizer)

Hier ist die vollständige Pipeline. Der VideoSummarizer Die Klasse verknüpft den Body-Extraktor, das Modell und eine Inferenzstrategie mit zwei Durchgängen: Der erste Durchgang generiert Beschreibungen professional Body und der zweite Durchgang synthetisiert diese Beschreibungen in einem strukturierten JSON-Bericht mit einer narrativen Zusammenfassung und extrahierten Aktionselementen.

Das Zwei-Move-Design ist bewusst. Das Modell zu bitten, jeweils nur einen einzelnen Body zu beschreiben, ist eine gezielte, erreichbare Aufgabe. es liefert genaue, konkrete Beschreibungen. Die Aufgabe, 30 Body-Beschreibungen zu einer kohärenten Erzählung zusammenzufassen, ist eine andere Aufgabe, und das kann besser als separater Aufruf mit den verketteten Beschreibungen als Eingabe erledigt werden, als wenn man versucht hätte, beides in einem Durchgang zu erledigen.

# video_summarizer.py
# Conditions: frame_extractor.py and smolvlm2_loader.py in the identical listing
# Run: python video_summarizer.py meeting_recording.mp4 --output abstract.json

import re
import json
import argparse
from dataclasses import dataclass, discipline
import cv2
import torch

from frame_extractor import FrameExtractor
from smolvlm2_loader import load_model, describe_frame


# ── Knowledge fashions ───────────────────────────────────────────────────────────────

@dataclass
class FrameDescription:
    timestamp: float
    frame_index: int
    description: str

@dataclass
class VideoSummary:
    video_path: str
    duration_seconds: float
    frames_analyzed: int
    frame_descriptions: listing(FrameDescription)
    narrative_summary: str
    action_items: listing(str) = discipline(default_factory=listing)
    key_moments: listing(dict) = discipline(default_factory=listing)


# ── Per-frame immediate ──────────────────────────────────────────────────────────

FRAME_PROMPT = """You're analyzing a body from a recorded assembly.

Describe what you see concisely however fully:
- Who or what's seen (folks, whiteboards, screens, slides)
- Any readable textual content (slide titles, whiteboard content material, display content material)
- The obvious exercise (presenting, discussing, writing, listening)

Preserve your response to 2-3 sentences."""

# ── Synthesis immediate ──────────────────────────────────────────────────────────

def build_synthesis_prompt(descriptions: listing(FrameDescription), period: float) -> str:
    """Construct the second-pass immediate that synthesizes body descriptions right into a report."""
    frames_text = "n".be part of(
        f"({int(d.timestamp // 60):02d}:{int(d.timestamp % 60):02d}) {d.description}"
        for d in descriptions
    )
    return f"""Under are time-stamped descriptions of frames from a {period:.0f}-second assembly recording.

{frames_text}

Based mostly on these descriptions, present:

1. NARRATIVE SUMMARY: A 3-5 sentence abstract of what the assembly coated, who participated (if seen), and what selections or conclusions had been reached.

2. ACTION ITEMS: A bullet listing of concrete duties or follow-ups talked about or implied within the assembly. Begin every with a touch (-).

3. KEY MOMENTS: A bullet listing of the 3-5 most important moments with their timestamps in (MM:SS) format.

Format your response with clear headings for every part."""


# ── Output parser ─────────────────────────────────────────────────────────────

def parse_action_items(textual content: str) -> listing(str):
    """Extract bullet-point motion objects from the synthesis output."""
    objects = ()
    for line in textual content.break up("n"):
        stripped = line.strip()
        if re.match(r"^(-*•)s+", stripped) or re.match(r"^d+.s+", stripped):
            clear = re.sub(r"^(-*•d.)+s*", "", stripped).strip()
            if clear and len(clear) > 5:
                objects.append(clear)
    return objects

def parse_key_moments(textual content: str) -> listing(dict):
    """Extract key moments with timestamps from the synthesis output."""
    moments = ()
    sample = re.compile(r"((d{2}:d{2}))s*(.+)")
    for match in sample.finditer(textual content):
        moments.append({
            "timestamp_label": match.group(1),
            "description": match.group(2).strip()
        })
    return moments


# ── Major summarizer class ─────────────────────────────────────────────────────

class VideoSummarizer:
    """
    Finish-to-end native video summarizer utilizing SmolVLM2-2.2B.
    Two-pass technique: per-frame descriptions + synthesis narrative.
    Works on scanned, digital, and live-recorded movies alike.
    """

    def __init__(self, batch_size: int = 8):
        """
        Args:
            batch_size: Frames to explain per inference batch.
                        Tune based mostly on VRAM: 8 for 8 GB, 16 for 16 GB.
                        Every body makes use of ~81 visible tokens; decrease batch = much less peak VRAM.
        """
        self.mannequin, self.processor = load_model()
        self.extractor = FrameExtractor(max_frames=50)
        self.batch_size = batch_size

    def _get_duration(self, video_path: str) -> float:
        cap = cv2.VideoCapture(video_path)
        frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
        fps    = cap.get(cv2.CAP_PROP_FPS) or 30.0
        cap.launch()
        return spherical(frames / fps, 2)

    def summarize(self, video_path: str, mode: str = "uniform") -> VideoSummary:
        """
        Summarize a video file.

        Args:
            video_path: Path to the video file (mp4, avi, mov, mkv)
            mode:       "uniform" for even protection, "keyframe" for scene adjustments

        Returns:
            VideoSummary with per-frame descriptions, narrative, and motion objects
        """
        period = self._get_duration(video_path)
        print(f"Video: {video_path} ({period:.0f}s)")

        # ── Move 1: Extract frames ─────────────────────────────────────────
        if mode == "keyframe":
            frames = self.extractor.keyframe_sample(video_path)
        else:
            frames = self.extractor.uniform_sample(video_path)

        print(f"Extracted {len(frames)} frames -- describing in batches of {self.batch_size}...")

        # ── Move 2: Describe every body ────────────────────────────────────
        descriptions: listing(FrameDescription) = ()

        for batch_start in vary(0, len(frames), self.batch_size):
            batch = frames(batch_start : batch_start + self.batch_size)

            for local_idx, (timestamp, img) in enumerate(batch):
                global_idx = batch_start + local_idx
                print(f"  ({global_idx + 1}/{len(frames)}) Describing body at {timestamp}s...")

                desc = describe_frame(
                    self.mannequin,
                    self.processor,
                    img,
                    immediate=FRAME_PROMPT,
                    max_new_tokens=128,   # Preserve body descriptions concise
                )
                descriptions.append(FrameDescription(
                    timestamp=timestamp,
                    frame_index=global_idx,
                    description=desc,
                ))

        # ── Move 3: Synthesis ──────────────────────────────────────────────
        print("nRunning synthesis cross...")

        synthesis_prompt = build_synthesis_prompt(descriptions, period)
        synthesis_messages = (
            {
                "position": "person",
                "content material": ({"kind": "textual content", "textual content": synthesis_prompt}),
            }
        )
        synthesis_text_input = self.processor.apply_chat_template(
            synthesis_messages,
            add_generation_prompt=True,
        )
        # Synthesis is text-only -- no photos on this cross
        synthesis_inputs = self.processor(
            textual content=synthesis_text_input,
            return_tensors="pt",
        ).to(self.mannequin.system)

        with torch.no_grad():
            synthesis_ids = self.mannequin.generate(
                **synthesis_inputs,
                max_new_tokens=512,
                do_sample=False,
            )

        synthesis_new = synthesis_ids(0)(synthesis_inputs("input_ids").form(-1):)
        synthesis_output = self.processor.decode(synthesis_new, skip_special_tokens=True).strip()

        action_items = parse_action_items(synthesis_output)
        key_moments  = parse_key_moments(synthesis_output)

        return VideoSummary(
            video_path=video_path,
            duration_seconds=period,
            frames_analyzed=len(descriptions),
            frame_descriptions=descriptions,
            narrative_summary=synthesis_output,
            action_items=action_items,
            key_moments=key_moments,
        )

    def to_json(self, abstract: VideoSummary) -> str:
        """Serialize a VideoSummary to formatted JSON."""
        return json.dumps({
            "video":            abstract.video_path,
            "duration_seconds": abstract.duration_seconds,
            "frames_analyzed":  abstract.frames_analyzed,
            "narrative":        abstract.narrative_summary,
            "action_items":     abstract.action_items,
            "key_moments":      abstract.key_moments,
            "frame_descriptions": (
                {
                    "timestamp":    d.timestamp,
                    "timestamp_label": f"{int(d.timestamp // 60):02d}:{int(d.timestamp % 60):02d}",
                    "description":  d.description,
                }
                for d in abstract.frame_descriptions
            ),
        }, indent=2, ensure_ascii=False)


# ── Entry level ───────────────────────────────────────────────────────────────

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Summarize a video with SmolVLM2-2.2B")
    parser.add_argument("video",   assist="Path to the enter video file")
    parser.add_argument("--output", default="abstract.json", assist="Output JSON file path")
    parser.add_argument("--mode",   default="uniform", selections=("uniform", "keyframe"))
    parser.add_argument("--batch-size", kind=int, default=8)
    args = parser.parse_args()

    summarizer = VideoSummarizer(batch_size=args.batch_size)
    end result = summarizer.summarize(args.video, mode=args.mode)

    output_str = summarizer.to_json(end result)
    with open(args.output, "w", encoding="utf-8") as f:
        f.write(output_str)

    print(f"nSummary saved to {args.output}")
    print(f"Frames analyzed: {end result.frames_analyzed}")
    print(f"Motion objects discovered: {len(end result.action_items)}")
    for merchandise in end result.action_items:
        print(f"  - {merchandise}")

So führen Sie aus:

# Uniform sampling (default) -- finest for conferences and lectures
python video_summarizer.py meeting_2026_06_14.mp4 --output meeting_summary.json

# Keyframe sampling -- finest for occasion detection, surveillance
python video_summarizer.py security_footage.mp4 --mode keyframe --output occasions.json

# Modify batch dimension to your VRAM (8 for 8 GB VRAM, 16 for 16 GB)
python video_summarizer.py long_lecture.mp4 --batch-size 4 --output lecture.json

Beispielausgabe (abstract.json):

{
  "video": "meeting_2026_06_14.mp4",
  "duration_seconds": 3247.0,
  "frames_analyzed": 50,
  "narrative": "The assembly centered on Q3 product planning ...",
  "action_items": (
    "Finalize API design doc by finish of June",
    "Schedule testing dash kickoff for July 1",
    "Share up to date Gantt chart with stakeholders"
  ),
  "key_moments": (
    {"timestamp_label": "00:00", "description": "Workforce introductions and agenda overview"},
    {"timestamp_label": "12:30", "description": "API structure diagram reviewed on display"},
    {"timestamp_label": "41:15", "description": "Motion objects summarized on whiteboard"}
  )
}

# Batch-Frames mit VRAM-Bewusstsein

Die Chargengröße in VideoSummarizer ist der wichtigste Knopf, um innerhalb Ihres VRAM-Budgets zu bleiben. Wenn es zu groß ist, treten Fehler aufgrund von nicht genügend Arbeitsspeicher auf. Zu klein und man wird unnötig langsamer. Hier ist die Berechnung:

SmolVLM2-2.2B-Gewichte belegen in bfloat16 etwa 4,5 GB. Jeder Body trägt etwa 81 Bild-Tokens zum Inferenzaufruf bei, und im 2,2-B-Maßstab beträgt der KV-Cache-Overhead etwa 0,5 MB professional Token. 20 % VRAM als Spielraum belassen:

# vram_calculator.py
# Estimate a secure batch dimension to your GPU earlier than working the pipeline

def compute_batch_size(vram_gb: float, tokens_per_frame: int = 81) -> int:
    """
    Estimate frames per inference batch for a given VRAM price range.

    Args:
        vram_gb:          Accessible GPU VRAM in gigabytes
        tokens_per_frame: Visible tokens per picture (81 for SmolVLM2)

    Returns:
        Protected batch dimension, minimal 1, most 50
    """
    MODEL_GB     = 4.5      # SmolVLM2-2.2B weights in bfloat16
    HEADROOM     = 0.80     # Use at most 80% of complete VRAM
    MB_PER_TOKEN = 0.5 / 1024  # GB per KV token at 2.2B scale (tough)

    usable_gb        = vram_gb * HEADROOM
    inference_budget = max(0.0, usable_gb - MODEL_GB)
    frames           = int(inference_budget / (tokens_per_frame * MB_PER_TOKEN))

    return max(1, min(frames, 50))


if __name__ == "__main__":
    for vram in (6.0, 8.0, 12.0, 16.0, 24.0):
        print(f"  {vram:.0f} GB VRAM → batch_size = {compute_batch_size(vram)}")

Vergleicht man dies mit einigen gängigen VRAM-Stufen, bekommt man einen Eindruck von der Obergrenze:

  6 GB  VRAM → batch_size = 16
  8 GB  VRAM → batch_size = 30
 12 GB  VRAM → batch_size = 50
 16 GB  VRAM → batch_size = 50
 24 GB  VRAM → batch_size = 50

Für lange Movies, bei denen Sie es sich nicht leisten können, bei einem Fehler von Null neu zu starten, fügen Sie einen JSON Traces (JSONL)-Streaming-Author hinzu, der die Beschreibung jedes Frames bei der Generierung beibehält:

# jsonl_writer.py -- drop-in checkpoint assist for long-video processing

import json

class JSONLWriter:
    """
    Writes body descriptions to a JSONL file as they're produced.
    Allows resume-from-checkpoint on lengthy movies -- if inference fails at
    body 30 of fifty, re-read the JSONL and skip already-processed frames.
    """
    def __init__(self, path: str):
        self.path = path
        self._fh  = open(path, "a", encoding="utf-8")  # Append mode for resume

    def write(self, document: dict):
        """Write one body document and flush instantly to disk."""
        self._fh.write(json.dumps(document, ensure_ascii=False) + "n")
        self._fh.flush()

    def already_processed(self) -> set(int):
        """Return the set of body indices already within the checkpoint file."""
        processed = set()
        attempt:
            with open(self.path, "r", encoding="utf-8") as f:
                for line in f:
                    document = json.masses(line)
                    processed.add(document.get("frame_index", -1))
        besides FileNotFoundError:
            cross
        return processed

    def shut(self):
        self._fh.shut()

    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.shut()

# Erweiterung der Pipeline (Zeitstempel und JSONL-Streaming)

Der Ausgabe-JSON dieser Pipeline ist bereits auf Body-Ebene mit einem Zeitstempel versehen. Um die Durchsuchbarkeit zu verbessern, ist ein Zusatz erforderlich: eine Bereinigung MM:SS Beschriftung auf jeder Bildbeschreibung, die direkt dem Scrubber des Videoplayers zugeordnet ist.

Fügen Sie diesen Nachbearbeitungsschritt hinzu to_json() Wenn Sie möchten, dass die Ausgabe direkt in einer Videoüberprüfungsoberfläche verwendet werden kann:

def timestamp_label(seconds: float) -> str:
    """Convert decimal seconds to MM:SS or HH:MM:SS label."""
    complete = int(seconds)
    h, the rest = divmod(complete, 3600)
    m, s = divmod(the rest, 60)
    if h > 0:
        return f"{h:02d}:{m:02d}:{s:02d}"
    return f"{m:02d}:{s:02d}"

Für lange Videoausgaben, die Sie in ein Downstream-System (eine Datenbank, eine Slack-Benachrichtigung, einen Dokumentindexer) streamen möchten, ersetzen Sie den Batch-Puffer-Ansatz durch eine JSONL-Ausgabe, bei der jede Zeile der Datensatz eines Frames ist. Das bedeutet, dass die Beschreibung des ersten Frames 30 Sekunden nach Beginn der Verarbeitung eines 90-minütigen Movies verfügbar ist, anstatt darauf zu warten, dass die gesamte Pipeline abgeschlossen ist, bevor etwas geschrieben wird.

Koppeln Sie den JSONL-Author mit JSONLWriter.already_processed() So implementieren Sie „Resume-from-Checkpoint“: Wenn die Pipeline bei Bild 35 von 50 abstürzt, starten Sie sie neu. Sie liest dann den vorhandenen Prüfpunkt, überspringt die ersten 35 Bilder und fährt mit Bild 36 fort. Bei langen Movies spart dies erheblich Zeit gegenüber dem Begin bei Null.

# Abschluss

SmolVLM2-2.2B befindet sich an einem wirklich nützlichen Punkt auf der Kompromisskurve zwischen Kapazität und Größe. Klein genug, um auf einer einzelnen Verbraucher-GPU ausgeführt zu werden, und leistungsfähig genug, um Videozusammenfassungen zu erstellen, die für echte Arbeitsabläufe tatsächlich nützlich sind. Der Body-as-Picture-Ansatz hält die Implementierung sauber: keine exotischen Video-Encoder, keine benutzerdefinierten Aufmerksamkeitsimplementierungen, nur der Commonplace Transformatoren API mit PIL-Bildern als Eingabe.

Die Besprechungszusammenfassung in diesem Artikel ist die Vorlage. Ersetzen FRAME_PROMPT mit einer Aufforderung, die auf Ihre Area abgestimmt ist, ändern build_synthesis_prompt() um alle strukturierten Felder zu extrahieren, die für Ihren Anwendungsfall wichtig sind, und die gleiche Pipeline eignet sich für Vorlesungsaufzeichnungen, Sicherheitsaufnahmen, exemplarische Vorgehensweisen zu Produktdemos oder Sporthighlights. Das Zwei-Durchlauf-Muster, zuerst die Beschreibung professional Body und dann die Synthese, gilt für alle, da das Modell einzelne Frames genau beschreibt und Beschreibungen zuverlässig synthetisiert.

Die Grenze von 50 Bildern ist ein Ausgangspunkt, keine Obergrenze. Bei {Hardware} mit höherem VRAM erhöhen max_frames auf 75 oder 100 und experimentieren Sie. Die Qualität skaliert bis zu einem gewissen Punkt mit der Bildabdeckung, und Ihr Synthesedurchlauf profitiert von mehr Materials, mit dem Sie arbeiten können.

Shittu Olumid ist ein Software program-Ingenieur und technischer Autor, der sich leidenschaftlich dafür einsetzt, modernste Technologien zu nutzen, um fesselnde Erzählungen zu erschaffen, mit einem scharfen Blick fürs Element und einem Gespür für die Vereinfachung komplexer Konzepte. Sie können Shittu auch auf finden Twitter.



[ad_2]

]]>
http://chatgpz.de/data-analytics/lokale-videozusammenfassungspipeline-frames-mit-smolvlm2-2-2b-verarbeiten/feed/ 0 19900
5 Open-Supply-Omni-KI-Modelle, die Textual content, Bilder, Audio und Video verarbeiten http://chatgpz.de/data-analytics/5-open-supply-omni-ki-modelle-die-textual-content-bilder-audio-und-video-verarbeiten/ http://chatgpz.de/data-analytics/5-open-supply-omni-ki-modelle-die-textual-content-bilder-audio-und-video-verarbeiten/#respond Sat, 27 Jun 2026 10:13:38 +0000 http://chatgpz.de/data-analytics/5-open-source-omni-ki-modelle-die-text-bilder-audio-und-video-verarbeiten/ [ad_1]

5 Open-Source-Omni-KI-Modelle, die Text, Bilder, Audio und Video verarbeiten

# Einführung

Vor einem Jahr wirkten Omni-KI-Modelle eher wie ein Zukunftsversprechen als etwas, das Entwickler tatsächlich nutzen könnten. Die meisten multimodalen Systeme waren immer noch auf mehrere separate Modelle angewiesen, die hinter den Kulissen arbeiteten: eines für Textual content, eines für Bilder, eines für Sprache und manchmal eines für Video. Die Idee eines einzigen Modells, das verschiedene Eingabetypen verstehen und in verschiedenen Formaten reagieren kann, erschien mir ehrgeizig.

Das beginnt sich zu ändern. Heutzutage können omni- und multimodale Open-Supply-Modelle Textual content, Bilder, Audio und Video auf viel einheitlichere Weise verstehen. Einige können Bilder und Dokumente analysieren, über Audio transkribieren oder argumentieren, Videobilder verstehen und in Textform antworten. Andere gehen noch einen Schritt weiter, indem sie Sprache und Bilder generieren oder multimodale Interaktion in Echtzeit unterstützen.

In diesem Leitfaden betrachten wir fünf Open-Supply-Omni-KI-Modelle, die diesen Bereich vorantreiben. Nicht jedes Modell auf dieser Liste ist ein vollständiges „Any-to-Any“-System, und diese Unterscheidung ist wichtig.

Einige Modelle akzeptieren viele Eingabetypen, generieren aber nur Textual content, während andere Sprache, Bildgenerierung oder Audio-Video-Interaktion in Echtzeit unterstützen. Das Ziel besteht darin, Ihnen zu helfen, zu verstehen, was jedes Modell tatsächlich leisten kann.

# 1. NVIDIA Nemotron 3 Nano Omni 30B A3B Argumentation

NVIDIA Nemotron 3 Nano Omni 30B A3B Argumentation ist ein leistungsstarkes offenes Omni-Modell, das für ein multimodales Verständnis auf Unternehmensebene entwickelt wurde. Es kann Video, Audio, Bilder und Textual content verarbeiten und dann textbasierte Antworten generieren.

Dies macht es nützlich für Aufgaben wie Video- und Sprachanalyse, Dokumentenintelligenz, Diagrammbegründung, optische Zeichenerkennung (OCR), Transkription, Verständnis grafischer Benutzeroberflächen (GUI) und multimodale Beantwortung von Fragen.

5 Open-Source-Omni-KI-Modelle, die Text, Bilder, Audio und Video verarbeiten
Bild von Wir stellen vor: NVIDIA Nemotron 3 Nano Omni

Das Modell basiert auf einer 31B-Parameter-Mamba2-Transformer-Hybrid-Combination-of-Consultants-Architektur mit etwa 3B aktiven Parametern professional Token. Dies hilft dabei, starke Argumentationsfähigkeiten mit effizienteren Schlussfolgerungen zu kombinieren.

Es unterstützt außerdem ein langes 256K-Token-Kontextfenster und eignet sich daher für die Analyse langer Dokumente, ausführlicher Transkripte, Besprechungsaufzeichnungen, Schulungsvideos und anderer umfangreicher Unternehmensinhalte.

Was Nemotron 3 Nano Omni auszeichnet, ist sein praktischer Fokus auf reale Arbeitsabläufe und nicht auf einfache multimodale Demos. Es ist für Anwendungsfälle wie Kundensupport, Medienanalyse, Dokumentenprüfung, KI-Assistenten, Browser-Agenten, E-Mail-Agenten und GUI-Automatisierung konzipiert.

Am besten für: Video- und Sprachanalyse, Dokumentenintelligenz, OCR, Diagrammverständnis, GUI-Workflows, automatische Spracherkennung (ASR) und multimodale Fragen und Antworten für Unternehmen.

# 2. Google Gemma 4 12B IT

Google Gemma 4 12B IT ist Teil der offenen Gemma-Modellfamilie von Google DeepMind und als kompaktes, effizientes multimodales Modell für lokale und selbst gehostete KI-Anwendungen konzipiert. Es kann Textual content-, Bild-, Audio- und Videoeingaben verarbeiten und dann textbasierte Antworten generieren.

Dies macht es nützlich für Aufgaben wie die visuelle Beantwortung von Fragen, das Verstehen von Dokumenten und PDFs, OCR, Diagrammverständnis, Audiotranskription, Sprachübersetzung, Codierung, Argumentation und multimodale Assistenten-Workflows.

5 Open-Source-Omni-KI-Modelle, die Text, Bilder, Audio und Video verarbeiten
Bild von InfoQ

Das 12B Unified-Modell ist besonders interessant, da es eine geberfreie multimodale Architektur verwendet. Anstatt sich auf separate Bild- oder Audio-Encoder zu verlassen, projiziert es Rohbild-Patches und Audio-Wellenformen über leichte lineare Schichten direkt in den Einbettungsraum des Sprachmodells.

Gemma 4 12B unterstützt ein langes 256K-Token-Kontextfenster, das für die Arbeit mit langen Dokumenten, großen Codebasen, ausgedehnten Konversationen und multimodalen Eingaben nützlich ist, die Textual content, Bilder, Audio- und Videobilder kombinieren.

Am besten für: effiziente multimodale Assistenten, Dokumentenverständnis, Bild- und Audio-Argumentation, Videobildanalyse, Kodierung, mehrsprachige Aufgaben und lokale KI-Anwendungen.

# 3. Qwen3-Omni 30B A3B Instruct

Qwen3-Omni 30B A3B Instruct ist eines der leistungsfähigsten offenen Omni-Modelle, die heute erhältlich sind. Es ist als natives, mehrsprachiges, omnimodales Finish-to-Finish-Modell konzipiert, das Textual content, Bilder, Audio und Video verarbeiten und dann sowohl in Textual content als auch in natürlicher Sprache reagieren kann.

Dies macht es nützlich für den Aufbau von KI-Assistenten, die in Echtzeit sehen, zuhören, verstehen und reagieren können. Es kann für Spracherkennung, Sprachübersetzung, Audiountertitelung, Musikanalyse, OCR, Beantwortung von Bildfragen, Videoverständnis und audiovisuellen Dialog verwendet werden.

5 Open-Source-Omni-KI-Modelle, die Text, Bilder, Audio und Video verarbeiten
Bild von Qwen/Qwen3-Omni-30B-A3B-Instruct

Das Modell verwendet eine Combination-of-Consultants-Architektur mit einem Thinker-Talker-Design. Der Thinker übernimmt das multimodale Verstehen und Denken, während der Talker eine natürliche Sprachausgabe ermöglicht. Dieses Design hilft Qwen3-Omni dabei, sowohl tiefes multimodales Denken als auch gesprochene Interaktion mit geringer Latenz zu unterstützen.

Eine seiner größten Stärken ist die Audio- und Videointeraktion in Echtzeit. Im Gegensatz zu vielen multimodalen Modellen, die in einem langsamen Add- und Antwortformat arbeiten, ist Qwen3-Omni für Streaming-Anwendungsfälle mit natürlichem Abwechseln und sofortigen Textual content- oder Sprachantworten konzipiert.

Es verfügt außerdem über eine starke Mehrsprachigkeitsunterstützung mit 119 Textsprachen, 19 Spracheingabesprachen und 10 Sprachausgabesprachen. Dies macht es besonders nützlich für globale Anwendungen, mehrsprachige Sprachassistenten, Eingabehilfen und Audio-Video-Systeme, die in verschiedenen Sprachen funktionieren müssen.

Das Besondere an Qwen3-Omni ist, dass es der Idee eines echten Omni-Assistenten sehr nahe kommt. Es versteht nicht nur mehrere Eingabetypen; Es kann außerdem natürliche Sprache erzeugen, Systemanweisungen folgen, agentenähnliche Arbeitsabläufe unterstützen und komplexe audiovisuelle Aufgaben bewältigen.

Am besten für: offene Omni-Assistenten, Echtzeit-Sprachinteraktion, Videoverständnis, Audio-Argumentation, mehrsprachige Anwendungen, audiovisueller Dialog und Textual content-/Sprachantworten.

# 4. DeepSeek Janus-Professional 7B

DeepSeek Janus-Professional 7B ist ein einheitliches multimodales Modell, das sich sowohl auf das visuelle Verständnis als auch auf die Bilderzeugung konzentriert. Es handelt sich nicht um ein vollständiges Omni-Modell für Textual content, Audio, Bild und Video, aber es ist ein wichtiges offenes Modell, da es Bildverständnis und Bilderstellung in einem einzigen Framework vereint.

Dies macht es nützlich für Aufgaben wie visuelle Beantwortung von Fragen, Bildbegründung, Bildunterschrift, Textual content-zu-Bild-Generierung und multimodale kreative Arbeitsabläufe.

Janus-Professional basiert auf DeepSeek-LLM-7B und verwendet ein neuartiges autoregressives Framework, das die visuelle Kodierung zum Verständnis und zur Generierung in verschiedene Pfade unterteilt. Dieses Design hilft bei der Lösung eines häufigen Issues in multimodalen Modellen, bei denen derselbe visuelle Encoder sowohl die Erkennung eines Bildes als auch die Generierung eines neuen Bildes unterstützen muss.

5 Open-Source-Omni-KI-Modelle, die Text, Bilder, Audio und Video verarbeiten
Bild von: deepseek-ai/Janus-Professional-7B

Für das Bildverständnis verwendet Janus-Professional SigLIP-L als Imaginative and prescient-Encoder und unterstützt 384 x 384 Bildeingänge. Für die Bildgenerierung wird ein spezieller Bild-Tokenizer verwendet, der es dem Modell ermöglicht, Bilder aus Textaufforderungen zu generieren.

Was Janus-Professional auszeichnet, ist seine einfache, aber effektive Architektur. Durch die Entkopplung des visuellen Verständnisses und der visuellen Generierung bei gleichzeitiger Verwendung eines einheitlichen Transformators wird das Modell flexibler und schneidet bei beiden Aufgaben intestine ab.

Am besten für: Bildverständnis, visuelles Denken, Bildunterschrift, visuelle Beantwortung von Fragen und Textual content-zu-Bild-Generierung.

# 5. MiniCPM-o 4.5

MiniCPM-o 4.5 ist eines der aufregendsten offenen Omni-Modelle, da es für Bild-, Sprach- und multimodales Vollduplex-Reside-Streaming konzipiert ist. Es kann Textual content, Bilder, Video und Audio verarbeiten und dann sowohl Textual content- als auch Sprachausgaben generieren.

Dies macht es nützlich für den Aufbau von Reside-KI-Assistenten, die gleichzeitig sehen, zuhören und sprechen können. Es kann für Sprachgespräche in Echtzeit, Videoverständnis, OCR, Dokumentenanalyse, visuelle Beantwortung von Fragen, Sprachinteraktion und multimodale Assistenten-Workflows verwendet werden.

Das Modell ist mit insgesamt 9B-Parametern aufgebaut und kombiniert Komponenten wie SigLIP2, Whisper-medium, CosyVoice2 und Qwen3-8B. Dies verleiht ihm starke visuelle, sprachliche und sprachliche Fähigkeiten und hält das Modell gleichzeitig klein genug für den praktischen lokalen Einsatz.

5 Open-Source-Omni-KI-Modelle, die Text, Bilder, Audio und Video verarbeiten
Bild von openbmb/MiniCPM-o-4_5

Was MiniCPM-o 4.5 auszeichnet, ist seine multimodale Vollduplex-Streaming-Fähigkeit. Im Gegensatz zu herkömmlichen multimodalen Modellen, die auf einen Add warten, bevor sie antworten, kann MiniCPM-o 4.5 kontinuierliche Video- und Audiostreams verarbeiten und gleichzeitig Textual content- und Sprachantworten generieren.

Es kann auch eine proaktive Interaktion unterstützen. Dies bedeutet, dass das Modell eine Reside-Szene kontinuierlich beobachten und entscheiden kann, wann es sprechen, kommentieren oder antworten soll, anstatt erst zu reagieren, nachdem der Benutzer eine direkte Aufforderung gegeben hat.

MiniCPM-o 4.5 ist auch stark im visuellen Verständnis und in der OCR. Es kann hochauflösende Bilder, Movies mit hohen FPS und Dokumente in verschiedenen Seitenverhältnissen verarbeiten und eignet sich daher für die Dokumentenanalyse, das Bildschirmverständnis und visuelle KI-Anwendungen in der realen Welt.

Ein weiterer großer Vorteil ist die Flexibilität bei der Bereitstellung. Das Modell unterstützt PyTorch Rückschluss auf NVIDIA-GPUs, zusammen mit lama.cpp, Ollama, GGUF quantisierte Modelle, vLLMUnd SGLang. Dies erleichtert Entwicklern die lokale Ausführung des Modells auf GPUs, PCs und sogar einigen Edge-Geräten.

Am besten für: multimodale Echtzeitassistenten, Reside-Video- und Audioverständnis, Sprachinteraktion, OCR, Dokumentenanalyse, Edge-KI und omnimodale Vollduplex-Anwendungen.

# Letzte Gedanken

Omni-Modelle werden immer wichtiger, da sich die KI von einfachen Chatbots zu Systemen entwickelt, die echte Menschen in realen Situationen nutzen können. In alltäglichen Arbeitsabläufen liegen Informationen nicht nur in einem Format vor. Menschen nutzen Textual content, Bilder, Dokumente, Audio, Video, Screenshots, Conferences, Diagramme und Reside-Gespräche. Damit KI wirklich nützlich ist, muss sie alle diese Eingaben auf natürliche Weise verstehen.

In der Vergangenheit bedeutete der Aufbau eines solchen Techniques normalerweise die Kombination mehrerer Modelle: eines für Sprache, eines für Imaginative and prescient, eines für OCR, eines für Textbegründung und eines für Generierung. Dieser Ansatz funktioniert, aber er erhöht die Komplexität, die Latenz und den technischen Aufwand. Jedes zusätzliche Modell erhöht die Anzahl der beweglichen Teile, die Entwickler verwalten müssen.

Der Wandel, den wir jetzt erleben, ist anders. Weitere Funktionen werden direkt in das Modell selbst integriert. Anstatt viele separate Systeme miteinander zu verbinden, beginnen Omni-Modelle, mehrere Modalitäten innerhalb einer einzigen Architektur zu verstehen. Dies macht die Interaktion in Echtzeit praktischer, da das Modell mit viel geringerer Latenz sehen, zuhören, schlussfolgern und reagieren kann.

Dies ist besonders wichtig für Reside-KI-Assistenten, Sprachagenten, Videoanalysetools, Doc-Intelligence-Systeme, Barrierefreiheitstools und Agenten-Workflows. Wenn multimodales Verständnis in das Modell integriert ist, wird das Erlebnis für den Benutzer reibungsloser und natürlicher.

Abid Ali Awan (@1abidaliawan) ist ein zertifizierter Datenwissenschaftler, der gerne Modelle für maschinelles Lernen erstellt. Derzeit konzentriert er sich auf die Erstellung von Inhalten und das Schreiben technischer Blogs zu maschinellem Lernen und Datenwissenschaftstechnologien. Abid verfügt über einen Grasp-Abschluss in Technologiemanagement und einen Bachelor-Abschluss in Telekommunikationstechnik. Seine Imaginative and prescient ist es, ein KI-Produkt mithilfe eines graphischen neuronalen Netzwerks für Schüler mit psychischen Erkrankungen zu entwickeln.

[ad_2]

]]>
http://chatgpz.de/data-analytics/5-open-supply-omni-ki-modelle-die-textual-content-bilder-audio-und-video-verarbeiten/feed/ 0 19579
So verarbeiten Sie große Datensätze in Python, auch wenn Sie Anfänger sind http://chatgpz.de/data-analytics/so-verarbeiten-sie-grosse-datensaetze-in-python-auch-wenn-sie-anfaenger-sind/ http://chatgpz.de/data-analytics/so-verarbeiten-sie-grosse-datensaetze-in-python-auch-wenn-sie-anfaenger-sind/#respond Thu, 18 Dec 2025 03:07:13 +0000 http://chatgpz.de/data-analytics/so-verarbeiten-sie-grosse-datensaetze-in-python-auch-wenn-sie-anfaenger-sind/ [ad_1]

So verarbeiten Sie große Datensätze in Python, auch wenn Sie Anfänger sindSo verarbeiten Sie große Datensätze in Python, auch wenn Sie Anfänger sind
Bild vom Autor

# Einführung

Die Arbeit mit großen Datensätzen in Python führt oft zu einem häufigen Drawback: Sie laden Ihre Daten mit Pandasund Ihr Programm wird langsamer oder stürzt vollständig ab. Dies geschieht normalerweise, weil Sie versuchen, alles gleichzeitig in den Speicher zu laden.

Die meisten Speicherprobleme haben ihren Ursprung in Wie Sie laden und verarbeiten Daten. Mit ein paar praktischen Techniken können Sie Datensätze verarbeiten, die viel größer sind als Ihr verfügbarer Speicher.

In diesem Artikel lernen Sie sieben Techniken für die effiziente Arbeit mit großen Datenmengen in Python kennen. Wir fangen einfach an und bauen dann auf, sodass Sie am Ende genau wissen, welcher Ansatz zu Ihrem Anwendungsfall passt.

🔗 Du findest die Code auf GitHub. Wenn Sie möchten, können Sie dies ausführen Beispieldatengenerator-Python-Skript um Beispiel-CSV-Dateien abzurufen und die Codeausschnitte zu verwenden, um sie zu verarbeiten.

# 1. Daten in Blöcken lesen

Der einsteigerfreundlichste Ansatz besteht darin, Ihre Daten in kleineren Teilen zu verarbeiten, anstatt alles auf einmal zu laden.

Stellen Sie sich ein Szenario vor, in dem Sie über einen großen Verkaufsdatensatz verfügen und den Gesamtumsatz ermitteln möchten. Der folgende Code demonstriert diesen Ansatz:

import pandas as pd

# Outline chunk measurement (variety of rows per chunk)
chunk_size = 100000
total_revenue = 0

# Learn and course of the file in chunks
for chunk in pd.read_csv('large_sales_data.csv', chunksize=chunk_size):
    # Course of every chunk
    total_revenue += chunk('income').sum()

print(f"Complete Income: ${total_revenue:,.2f}")

Anstatt alle 10 Millionen Zeilen auf einmal zu laden, laden wir 100.000 Zeilen gleichzeitig. Wir berechnen die Summe für jeden Brocken und addieren sie zu unserer laufenden Summe. Ihr RAM fasst immer nur 100.000 Zeilen, egal wie groß die Datei ist.

Wann ist dies zu verwenden?: Wenn Sie Aggregationen (Summe, Anzahl, Durchschnitt) oder Filtervorgänge für große Dateien durchführen müssen.

# 2. Verwenden Sie nur bestimmte Spalten

Oft benötigen Sie nicht jede Spalte in Ihrem Datensatz. Wenn Sie nur das laden, was Sie brauchen, kann die Speichernutzung erheblich reduziert werden.

Angenommen, Sie analysieren Kundendaten, benötigen jedoch nur das Alter und den Kaufbetrag und nicht die zahlreichen anderen Spalten:

import pandas as pd

# Solely load the columns you really need
columns_to_use = ('customer_id', 'age', 'purchase_amount')

df = pd.read_csv('prospects.csv', usecols=columns_to_use)

# Now work with a a lot lighter dataframe
average_purchase = df.groupby('age')('purchase_amount').imply()
print(average_purchase)

Durch Angabe usecolslädt Pandas nur diese drei Spalten in den Speicher. Wenn Ihre Originaldatei 50 Spalten hätte, haben Sie Ihren Speicherverbrauch gerade um etwa 94 % reduziert.

Wann ist dies zu verwenden?: Wenn Sie vor dem Laden der Daten genau wissen, welche Spalten Sie benötigen.

# 3. Datentypen optimieren

Standardmäßig verbraucht Pandas möglicherweise mehr Speicher als nötig. Eine Spalte mit Ganzzahlen könnte als 64-Bit gespeichert werden, während 8-Bit intestine funktionieren würde.

Wenn Sie beispielsweise einen Datensatz mit Produktbewertungen (1–5 Sterne) und Benutzer-IDs laden:

import pandas as pd

# First, let's have a look at the default reminiscence utilization
df = pd.read_csv('scores.csv')
print("Default reminiscence utilization:")
print(df.memory_usage(deep=True))

# Now optimize the information varieties
df('ranking') = df('ranking').astype('int8')  # Scores are 1-5, so int8 is sufficient
df('user_id') = df('user_id').astype('int32')  # Assuming person IDs slot in int32

print("nOptimized reminiscence utilization:")
print(df.memory_usage(deep=True))

Durch Umrechnung der Bewertungsspalte vom Wahrscheinlichen int64 (8 Bytes professional Zahl) bis int8 (1 Byte professional Zahl) erreichen wir eine 8-fache Speicherreduzierung für diese Spalte.

Zu den gängigen Konvertierungen gehören:

  • int64 → int8, int16oder int32 (abhängig vom Zahlenbereich).
  • float64 → float32 (wenn Sie keine excessive Präzision benötigen).
  • object → class (für Spalten mit wiederholten Werten).

# 4. Verwenden Sie kategoriale Datentypen

Wenn eine Spalte wiederholte Textwerte enthält (wie Ländernamen oder Produktkategorien), speichert Pandas jeden Wert separat. Der class dtype speichert die eindeutigen Werte einmal und verwendet effiziente Codes, um darauf zu verweisen.

Angenommen, Sie arbeiten mit einer Produktinventardatei, in der die Kategoriespalte nur 20 eindeutige Werte enthält, diese sich jedoch in allen Zeilen im Datensatz wiederholen:

import pandas as pd

df = pd.read_csv('merchandise.csv')

# Examine reminiscence earlier than conversion
print(f"Earlier than: {df('class').memory_usage(deep=True) / 1024**2:.2f} MB")

# Convert to class
df('class') = df('class').astype('class')

# Examine reminiscence after conversion
print(f"After: {df('class').memory_usage(deep=True) / 1024**2:.2f} MB")

# It nonetheless works like regular textual content
print(df('class').value_counts())

Diese Konvertierung kann die Speichernutzung für Spalten mit geringer Kardinalität (wenige eindeutige Werte) erheblich reduzieren. Die Funktion der Spalte ähnelt weiterhin den Standardtextdaten: Sie können wie gewohnt filtern, gruppieren und sortieren.

Wann ist dies zu verwenden?: Für jede Textspalte, in der sich Werte häufig wiederholen (Kategorien, Staaten, Länder, Abteilungen und dergleichen).

# 5. Filtern Sie beim Lesen

Manchmal wissen Sie, dass Sie nur eine Teilmenge von Zeilen benötigen. Anstatt alles zu laden und dann zu filtern, können Sie während des Ladevorgangs filtern.

Wenn Sie beispielsweise nur Transaktionen aus dem Jahr 2024 interessieren:

import pandas as pd

# Learn in chunks and filter
chunk_size = 100000
filtered_chunks = ()

for chunk in pd.read_csv('transactions.csv', chunksize=chunk_size):
    # Filter every chunk earlier than storing it
    filtered = chunk(chunk('12 months') == 2024)
    filtered_chunks.append(filtered)

# Mix the filtered chunks
df_2024 = pd.concat(filtered_chunks, ignore_index=True)

print(f"Loaded {len(df_2024)} rows from 2024")

Wir kombinieren Chunking mit Filtern. Jeder Block wird gefiltert, bevor er zu unserer Liste hinzugefügt wird, sodass wir nie den gesamten Datensatz im Speicher behalten, sondern nur die Zeilen, die wir tatsächlich benötigen.

Wann ist dies zu verwenden?: Wenn Sie basierend auf einer Bedingung nur eine Teilmenge von Zeilen benötigen.

# 6. Verwenden Sie Dask für die Parallelverarbeitung

Für Datensätze, die wirklich umfangreich sind, Dask stellt eine Pandas-ähnliche API bereit, übernimmt jedoch die gesamte Chunking- und Parallelverarbeitung automatisch.

So würden Sie den Durchschnitt einer Spalte in einem großen Datensatz berechnen:

import dask.dataframe as dd

# Learn with Dask (it handles chunking mechanically)
df = dd.read_csv('huge_dataset.csv')

# Operations look similar to pandas
outcome = df('gross sales').imply()

# Dask is lazy - compute() really executes the calculation
average_sales = outcome.compute()

print(f"Common Gross sales: ${average_sales:,.2f}")

Dask lädt nicht die gesamte Datei in den Speicher. Stattdessen erstellt es einen Plan für die Verarbeitung der Daten in Blöcken und führt diesen Plan aus, wenn Sie ihn aufrufen .compute(). Es können sogar mehrere CPU-Kerne verwendet werden, um die Berechnung zu beschleunigen.

Wann ist dies zu verwenden?: Wenn Ihr Datensatz zu groß für Pandas ist, selbst mit Chunking, oder wenn Sie eine parallele Verarbeitung wünschen, ohne komplexen Code zu schreiben.

# 7. Proben Sie Ihre Daten zur Erkundung

Wenn Sie nur Code erkunden oder testen, benötigen Sie nicht den vollständigen Datensatz. Laden Sie zuerst eine Probe.

Angenommen, Sie erstellen ein Modell für maschinelles Lernen und möchten Ihre Vorverarbeitungspipeline testen. Sie können Ihren Datensatz wie gezeigt testen:

import pandas as pd

# Learn simply the primary 50,000 rows
df_sample = pd.read_csv('huge_dataset.csv', nrows=50000)

# Or learn a random pattern utilizing skiprows
import random
skip_rows = lambda x: x > 0 and random.random() > 0.01  # Preserve ~1% of rows

df_random_sample = pd.read_csv('huge_dataset.csv', skiprows=skip_rows)

print(f"Pattern measurement: {len(df_random_sample)} rows")

Der erste Ansatz lädt die ersten N Zeilen, was für eine schnelle Erkundung geeignet ist. Beim zweiten Ansatz werden zufällig Zeilen in der gesamten Datei abgetastet. Dies eignet sich besser für statistische Analysen oder wenn die Datei so sortiert ist, dass die obersten Zeilen nicht repräsentativ sind.

Wann ist dies zu verwenden?: Während der Entwicklung, beim Testen oder bei der explorativen Analyse, bevor Sie Ihren Code für den gesamten Datensatz ausführen.

# Abschluss

Der Umgang mit großen Datensätzen erfordert keine Expertenkenntnisse. Hier ist eine kurze Zusammenfassung der Techniken, die wir besprochen haben:

Technik Wann sollte man es verwenden?
Chunking

Für Aggregationen, Filterung und Verarbeitung von Daten reicht der Arbeitsspeicher nicht aus.

Spaltenauswahl

Wenn Sie nur wenige Spalten aus einem umfangreichen Datensatz benötigen.

Datentypoptimierung

Stets; Tun Sie dies nach dem Laden, um Speicherplatz zu sparen.

Kategoriale Typen

Für Textspalten mit wiederholten Werten (Kategorien, Zustände usw.).

Filtern Sie beim Lesen

Wenn Sie nur eine Teilmenge von Zeilen benötigen.

Dask

Für sehr große Datensätze oder wenn Sie eine parallele Verarbeitung wünschen.

Probenahme

Während der Entwicklung und Erforschung.

Der erste Schritt besteht darin, sowohl Ihre Daten als auch Ihre Aufgabe zu kennen. In den meisten Fällen reicht eine Kombination aus Chunking und intelligenter Spaltenauswahl aus, um 90 % des Ziels zu erreichen.

Wenn Ihre Anforderungen wachsen, wechseln Sie zu fortschrittlicheren Instruments wie Dask oder erwägen Sie die Konvertierung Ihrer Daten in effizientere Dateiformate wie Parkett oder HDF5.

Beginnen Sie nun mit der Arbeit mit diesen riesigen Datensätzen. Viel Spaß beim Analysieren!

Bala Priya C ist ein Entwickler und technischer Redakteur aus Indien. Sie arbeitet gerne an der Schnittstelle von Mathematik, Programmierung, Datenwissenschaft und Inhaltserstellung. Zu ihren Interessen- und Fachgebieten gehören DevOps, Datenwissenschaft und Verarbeitung natürlicher Sprache. Sie liebt es zu lesen, zu schreiben, zu programmieren und Kaffee zu trinken! Derzeit arbeitet sie daran, zu lernen und ihr Wissen mit der Entwickler-Neighborhood zu teilen, indem sie Tutorials, Anleitungen, Meinungsbeiträge und mehr verfasst. Bala erstellt außerdem ansprechende Ressourcenübersichten und Programmier-Tutorials.



[ad_2]

]]>
http://chatgpz.de/data-analytics/so-verarbeiten-sie-grosse-datensaetze-in-python-auch-wenn-sie-anfaenger-sind/feed/ 0 14915
Verwenden von Visionsprachmodellen, um Millionen von Dokumenten zu verarbeiten http://chatgpz.de/machine-learning/verwenden-von-visionsprachmodellen-um-millionen-von-dokumenten-zu-verarbeiten/ http://chatgpz.de/machine-learning/verwenden-von-visionsprachmodellen-um-millionen-von-dokumenten-zu-verarbeiten/#respond Mon, 29 Sep 2025 08:42:07 +0000 http://chatgpz.de/machine-learning/verwenden-von-visionsprachmodellen-um-millionen-von-dokumenten-zu-verarbeiten/ [ad_1]

(VLMs) sind leistungsstarke Modelle für maschinelles Lernen, die sowohl visuelle als auch textuelle Informationen verarbeiten können. Mit der jüngsten Veröffentlichung von QWEN 3 VL möchte ich einen tiefen Eintauchen in die Verarbeitung dieser leistungsstarken VLMs machen, um Dokumente zu verarbeiten.

Inhaltsverzeichnis

Warum Sie VLMs verwenden müssen

Um hervorzuheben, warum einige Aufgaben VLMs erfordern, möchte ich mit einer Beispielaufgabe beginnen, bei der wir Textual content und die visuellen Informationen des Textes interpretieren müssen.

Stellen Sie sich vor, Sie sehen sich das Bild unten an. Die Kontrollkästchen stellen dar, ob ein Dokument in einen Bericht enthalten sein soll oder nicht, und jetzt müssen Sie feststellen, welche Dokumente einbezogen werden sollen.

Diese Abbildung zeigt ein geeignetes Downside für VLMs. Sie haben ein Bild mit Textual content zu Dokumenten sowie Kontrollkästchen. Sie müssen nun feststellen, welche Dokumente die Kontrollkästchen untersucht wurden. Dies ist schwer mit LLMs zu lösen, da Sie zuerst OCR auf das Bild anwenden müssen. Der Textual content verliert dann seine visuelle Place, die erforderlich ist, um die Aufgabe richtig zu lösen. Mit VLMs können Sie den Textual content problemlos im Dokument lesen und seine visuelle Place verwenden (wenn der Textual content über einem Kontrollkästchen überprüft wird oder nicht) und die Aufgabe erfolgreich lösen. Bild des Autors.

Für einen Menschen ist dies eine einfache Aufgabe; Offensichtlich sollten die Dokumente 1 und 3 enthalten sein, während Dokument 2 ausgeschlossen werden sollte. Wenn Sie jedoch versucht haben, dieses Downside durch ein reines LLM zu lösen, würden Sie auf Probleme stoßen.

Um ein reines LLM auszuführen, müssen Sie zunächst das Bild OCR benötigen, wo die OCR -Ausgabe ungefähr wie unten aussehen würde, wenn Sie verwenden Googles TesseractZum Beispiel, der die Textzeile nach Zeile extrahiert.

Doc 1  Doc 2  Doc 3  X   X 

Wie Sie vielleicht bereits entdeckt haben, wird die LLM Probleme haben, welche Dokumente enthalten sind, da es unmöglich ist, zu wissen, zu welchen Dokumenten das XS gehört. Dies ist nur eines von vielen Szenarien, in denen VLMs äußerst effizient darin sind, ein Downside zu lösen.

Der Hauptpunkt hier ist, dass das Wissen, welche Dokumente ein Kontrollkästchen X haben, sowohl visuelle als auch Textinformationen erfordert. Sie müssen den Textual content und die visuelle Place des Textes im Bild kennen. Ich fasse dies im folgenden Zitat zusammen:

VLMs sind erforderlich, wenn die Bedeutung des Textes von seiner visuellen Place abhängt

Anwendungsbereiche

Es gibt eine Vielzahl von Bereichen, auf die Sie VLMs anwenden können. In diesem Abschnitt werde ich einige verschiedene Bereiche abdecken, in denen sich VLMs als nützlich erwiesen haben und in denen ich auch VLMs erfolgreich angewendet habe.

Agierische Anwendungsfälle

Die Agenten sind heutzutage im Wind und VLMs spielen auch eine Rolle. Ich werde zwei Hauptbereiche hervorheben, in denen VLMs in einem Agentenkontext verwendet werden können, obwohl es natürlich viele andere solche Bereiche gibt.

Computergebrauch

Der Computergebrauch ist ein interessanter Anwendungsfall für VLMs. Mit dem Computergebrauch beziehe ich mich auf einen VLM, der einen Body von Ihrem Pc aus betrachtet und entscheide, welche Aktion als nächstes ergriffen werden soll. Ein Beispiel dafür ist Openai -Betreiber. Dies kann beispielsweise einen Bild dieses Artikels betrachten, den Sie gerade lesen, und nach unten zu scrollen, um mehr aus diesem Artikel zu lesen.

VLMs sind nützlich für den Computergebrauch, da LLMs nicht ausreichen, um zu entscheiden, welche Aktionen ergriffen werden müssen. Wenn Sie auf einem Pc arbeiten, müssen Sie häufig die visuelle Place von Schaltflächen und Informationen interpretieren, die, wie ich am Anfang beschrieben habe, einer der Hauptnutzungsbereiche für VLMs ist.

Debuggen

Der Debugging -Code ist auch ein tremendous nützlicher Agentenanwendungsbereich für VLMs. Stellen Sie sich vor, Sie entwickeln eine Webanwendung und entdecken Sie einen Fehler.

Eine Möglichkeit besteht darin, sich bei der Konsole anzumelden, die Protokolle zu kopieren, Cursor zu beschreiben, was Sie getan haben, und den Cursor fordern, um ihn zu beheben. Dies ist natürlich zeitaufwändig, da der Benutzer viele manuelle Schritte erfordert.

Eine andere Possibility besteht daher darin, VLMs zu verwenden, um das Downside besser zu lösen. Im Idealfall beschreiben Sie, wie Sie das Downside reproduzieren. Ein VLM kann in Ihre Anwendung eingehen, den Fluss neu erstellen, das Downside überprüfen und so debuggen, was schief geht. Für Bereiche wie diese werden Anwendungen erstellt, obwohl die meisten nicht weit in der Entwicklung von dem gekommen sind, was ich gesehen habe.

Frage Beantwortung

Die Verwendung von VLMs für die Beantwortung der visuellen Frage ist einer der klassischen Ansätze für die Verwendung von VLMs. Die Beantwortung von Frage ist der Anwendungsfall, den ich früher in diesem Artikel beschrieben habe, um herauszufinden, welches Kontrollkästchen zu welchen Dokumenten gehört. Sie füttern die VLM mit einer Benutzerfrage und einem Bild (oder mehreren Bildern), damit die VLM verarbeitet werden kann. Das VLM liefert dann eine Antwort im Textformat. Sie können sehen, wie dieser Prozess in der Abbildung unten funktioniert.

Diese Abbildung zeigt eine Fragenbeantwortungsaufgabe, bei der ich ein VLM verwendet habe, um das Downside zu lösen. Sie füttern das Bild, das das Downside enthält, und die Frage, die die zu lösene Aufgabe enthält. Das VLM verarbeitet diese Informationen dann und gibt die erwarteten Informationen aus. Bild des Autors,

Sie sollten jedoch die Kompromisse bei der Verwendung von VLMS vs LLMs abwägen. Wenn eine Aufgabe Textual content- und visuelle Informationen erfordert, müssen Sie natürlich VLMs verwenden, um ein ordnungsgemäßes Ergebnis zu erzielen. VLMs sind jedoch in der Regel auch viel teurer zu betreiben, da sie mehr Token verarbeiten müssen. Dies liegt daran, dass Bilder viele Informationen enthalten, was somit zu vielen Eingabestellen führt.

Wenn das VLM Textual content verarbeiten soll, benötigen Sie außerdem hochauflösende Bilder, sodass die VLM die Pixel interpretieren kann, die Buchstaben ausmachen. Mit niedrigeren Auflösungen bemüht sich das VLM, den Textual content in den Bildern zu lesen, und Sie erhalten minderwertige Ergebnisse.

Einstufung

Diese Abbildung behandelt, wie Sie VLMs auf Klassifizierungsaufgaben anwenden können. Sie füttern das VLM mit einem Bild eines Dokuments und der Frage, um das Dokument in einen vordefinierten Kategoriensatz zu klassifizieren. Diese Kategorien sollten in die Frage einbezogen werden, sind jedoch aufgrund von Platzbeschränkungen nicht in die Abbildung enthalten. Das VLM gibt dann das vorhergesagte Klassifizierungsetikett aus. Bild des Autors.

Ein weiterer interessanter Anwendungsbereich für VLMs ist die Klassifizierung. Bei der Klassifizierung beziehe ich mich auf die State of affairs, in der Sie einen festgelegten Kategoriensatz haben und feststellen müssen, zu welcher Kategorie ein Bild gehört.

Sie können VLMs zur Klassifizierung verwenden, wobei der gleiche Ansatz wie die Verwendung von LLMs verwendet wird. Sie erstellen eine strukturierte Eingabeaufforderung mit allen relevanten Informationen, einschließlich der möglichen Ausgabekategorien. Darüber hinaus decken Sie vorzugsweise die verschiedenen Randfälle ab, beispielsweise in Szenarien, in denen beide Kategorien sehr wahrscheinlich sind, und die VLM muss sich zwischen den beiden Kategorien entscheiden.

Sie können beispielsweise eine Eingabeaufforderung haben wie:

def get_prompt():
    return """
        ## Basic directions
        It's essential to decide which class a given doc belongs to. 
        The obtainable classes are "authorized", "technical", "monetary".

        ## Edge case dealing with
        - Within the state of affairs the place you've got a authorized doc overlaying monetary info, the doc belongs to the monetary class
        - ...
        ## Return format
        Reply solely with the corresponding class, and no different textual content 
    """

Sie können VLMs auch effektiv zur Informationsextraktion verwenden, und es gibt viele Aufgaben zur Informationsextraktion, die visuelle Informationen erfordern. Sie erstellen eine ähnliche Eingabeaufforderung wie die oben erstellte Klassifizierungsaufforderung und fordern normalerweise die VLM auf, in einem strukturierten Format wie einem JSON -Objekt zu reagieren.

Bei der Durchführung der Informationsextraktion müssen Sie überlegen, wie viele Datenpunkte Sie extrahieren möchten. Wenn Sie beispielsweise 20 verschiedene Datenpunkte aus einem Dokument extrahieren müssen, möchten Sie wahrscheinlich nicht alle gleichzeitig extrahieren. Dies liegt daran, dass das Modell wahrscheinlich Schwierigkeiten hat, so viele Informationen auf einmal genau zu extrahieren.

Stattdessen sollten Sie in Betracht ziehen, die Aufgabe beispielsweise mit zwei verschiedenen Anforderungen zu extrahieren und die Aufgabe für das Modell zu vereinfachen. Auf der anderen Seite des Arguments begegnen Sie manchmal, dass einige Datenpunkte miteinander zusammenhängen, was bedeutet, dass sie in derselben Anfrage extrahiert werden sollten. Darüber hinaus erhöht das Senden mehrerer Anfragen die Inferenzkosten.

Diese Abbildung zeigt, wie Sie VLMs verwenden können, um die Informationsextraktion durchzuführen. Sie füttern das VLM erneut mit dem Bild des Dokuments und fordern auch die VLM auf, bestimmte Datenpunkte zu extrahieren. In dieser Abbildung fordere ich die VLM auf, das Datum des Dokuments, den im Dokument genannten Ort und den Dokumenttyp zu extrahieren. Das VLM analysiert dann die Eingabeaufforderung und das Dokumentbild und gibt ein JSON -Objekt aus, das die angeforderten Informationen enthält. Bild des Autors.

Wenn VLMs problematisch sind

VLMs sind erstaunliche Modelle, die Aufgaben ausführen können, die vor wenigen Jahren unvorstellbar waren, mit KI zu lösen. Sie haben jedoch auch ihre Grenzen, die ich in diesem Abschnitt abdecken werde.

Kosten für den Betrieb von VLMs

Die erste Einschränkung sind die Kosten für den Betrieb von VLMs, die ich auch früher in diesem Artikel kurz erörtert habe. VLMs verarbeiten Bilder, die aus vielen Pixeln bestehen. Diese Pixel repräsentieren viele Informationen, die in Token codiert sind, die das VLM verarbeiten kann. Das Downside ist, dass Sie, da Bilder so viele Informationen enthalten, viele Token professional Bild erstellen müssen, was die Kosten für den Ausführen von VLMs wieder erhöht.

Darüber hinaus benötigen Sie häufig hochauflösende Bilder, da das VLM in den Bildern Textual content lesen muss, was zu noch mehr Token führt. VLMs sind somit teuer zu laufen, beide über eine API, aber in Berechnung, wenn Sie sich entscheiden, die VLM selbst zu veranstalten.

Lange Dokumente können nicht verarbeitet werden

Die in den Bildern enthaltene Menge an Token begrenzt auch die Anzahl der Seiten, die ein VLM sofort verarbeiten kann. VLMs sind wie herkömmliche LLMs durch ihre Kontextfenster begrenzt. Dies ist ein Downside, wenn Sie lange Dokumente mit Hunderten von Seiten verarbeiten möchten. Natürlich können Sie das Dokument in Stücke aufteilen, aber Sie könnten auf Probleme stoßen, bei denen der VLM keinen Zugriff auf alle Inhalte des Dokuments auf einmal hat.

Wenn Sie beispielsweise ein 100-seitiges Dokument haben, können Sie zuerst die Seiten 1-50 verarbeiten und dann die Seiten 51-100 verarbeiten. Wenn einige Informationen auf Seite 53 möglicherweise den Kontext von Seite 1 (z. B. dem Titel oder Datum des Dokuments) benötigen, führt dies zu Problemen.

Um zu lernen, wie man mit diesem Downside umgeht, habe ich das Kochbuch von Qwen 3 gelesen, auf dem sie eine Seite haben So verwenden Sie Qwen 3 für ultralong -Dokumente. Ich werde dies sicher testen und diskutieren, wie intestine es in einem zukünftigen Artikel funktioniert.

Abschluss

In diesem Artikel habe ich Imaginative and prescient Language -Modelle diskutiert und wie Sie sie auf verschiedene Problembereiche anwenden können. Ich habe zunächst beschrieben, wie VLMs in Agentensysteme integriert werden, beispielsweise als Pc -Use -Agent oder um Webanwendungen zu debuggen. Durch Fortsetzung behandelte ich Bereiche wie die Beantwortung von Fragen, Klassifizierung und Informationsextraktion. Zuletzt habe ich auch einige Einschränkungen von VLMs behandelt und die Berechnungskosten für den Betrieb von VLMs und die Artwork und Weise, wie sie mit langen Dokumenten zu kämpfen haben, diskutierte.

👉 Finden Sie mich in Socials:

🧑‍💻 Sich in Verbindung setzen

🔗 LinkedIn

🐦 X / Twitter

✍ Medium

[ad_2]

]]>
http://chatgpz.de/machine-learning/verwenden-von-visionsprachmodellen-um-millionen-von-dokumenten-zu-verarbeiten/feed/ 0 12779
Entscheidungsbäume verarbeiten kategoriale Daten nativ http://chatgpz.de/machine-learning/entscheidungsbaeume-verarbeiten-kategoriale-daten-nativ/ http://chatgpz.de/machine-learning/entscheidungsbaeume-verarbeiten-kategoriale-daten-nativ/#respond Mon, 09 Jun 2025 07:50:25 +0000 https://chatgpz.de/machine-learning/entscheidungsbaeume-verarbeiten-kategoriale-daten-nativ/ [ad_1]

Algorithmen für maschinelles Lernen können kategoriale Variablen nicht verarbeiten. Aber Entscheidungsbäume (DTs) können. Klassifizierungsbäume erfordern auch kein numerisches Ziel. Unten ist eine Darstellung eines Baumes, der eine Untergruppe von kyrillischen Buchstaben in Vokale und Konsonanten einteiliert. Es verwendet keine numerischen Merkmale – es existiert jedoch.

Viele fördern auch die mittlere Zielcodierung (MTE) als clevere Methode, um kategoriale Daten in numerische Kind umzuwandeln-ohne den Merkmalsraum als One-Scorching-Codierung aufzublasen. Ich habe jedoch keine Erwähnung dieser inhärenten Verbindung zwischen MTE und Resolution Tree Logic zu TDs gesehen. Dieser Artikel befasst sich genau mit dieser Lücke durch ein veranschaulichendes Experiment. Insbesondere:

  • Ich werde mit einer kurzen Zusammenfassung der Artwork und Weise beginnen, wie Entscheidungsbäume Behandeln Sie kategoriale Merkmale.
  • Wir werden sehen, dass dies zu einer rechnerischen Herausforderung für Funktionen mit hoher Kardinalität wird.
  • Ich werde demonstrieren, wie die mittlere Zielcodierung auf natürliche Weise als Lösung für dieses Downside auftritt – im Gegensatz zu Beschriftungscodierung.
  • Sie können mein Experiment mit dem Code aus reproduzieren Github.
Dieser einfache Entscheidungsbaum (ein Entscheidungsstumpf) verwendet keine numerischen Merkmale – er existiert jedoch. Bild vom Autor mit Hilfe von Chatgpt-4o erstellt

Ein kurzer Hinweis: One-Scorching-Codierung wird oft von Followers der mittleren Zielcodierung ungünstig dargestellt-aber es ist nicht so schlimm, wie sie vermuten lassen. Tatsächlich belegte es in unseren Benchmark -Experimenten häufig den ersten Platz unter den 32 kategorialen Codierungsmethoden, die wir bewertet haben. (1)

Entscheidungsbäume und der Fluch der kategorialen Merkmale

Entscheidungsbaumlernen ist ein rekursiver Algorithmus. Bei jedem rekursiven Schritt iteriert es alle Funktionen und sucht nach dem besten Cut up. Es reicht additionally aus, zu untersuchen, wie eine einzige rekursive Iteration mit einem kategorialen Merkmal umgeht. Wenn Sie sich nicht sicher sind, wie sich diese Operation auf die Konstruktion des vollen Baumes verallgemeinert, schauen Sie sich hier an (2).

Für eine kategoriale Funktion bewertet der Algorithmus alle möglichen Möglichkeiten, die Kategorien in zwei nicht leere Sätze zu unterteilen, und wählt die aus, die die höchste Cut up -Qualität ergibt. Die Qualität wird typischerweise unter Verwendung von Gini -Verunreinigungen für binäre Klassifizierung oder mittlerer quadratischer Fehler für die Regression gemessen – beide sind besser, wenn sie niedriger sind. Siehe ihren Pseudocode unten.

# ----------  Gini impurity criterion  ----------
FUNCTION GiniImpurityForSplit(cut up):
    left, proper = cut up
    complete = dimension(left) + dimension(proper)
    RETURN (dimension(left)/complete)  * GiniOfGroup(left) +
           (dimension(proper)/complete) * GiniOfGroup(proper)

FUNCTION GiniOfGroup(group):
    n = dimension(group)
    IF n == 0: RETURN 0
    ones  = rely(values equal 1 in group)
    zeros = n - ones
    p1 = ones / n
    p0 = zeros / n
    RETURN 1 - (p0² + p1²)
# ----------  Imply-squared-error criterion  ----------
FUNCTION MSECriterionForSplit(cut up):
    left, proper = cut up
    complete = dimension(left) + dimension(proper)
    IF complete == 0: RETURN 0
    RETURN (dimension(left)/complete)  * MSEOfGroup(left) +
           (dimension(proper)/complete) * MSEOfGroup(proper)

FUNCTION MSEOfGroup(group):
    n = dimension(group)
    IF n == 0: RETURN 0
    μ = imply(Worth column of group)
    RETURN sum( (v − μ)² for every v in group ) / n

Nehmen wir an, die Funktion hat eine Kardinalität okay. Jede Kategorie kann zu einer der beiden Sätze gehören, die 2 gebenᵏ Gesamtkombinationen. Ohne die beiden trivialen Fälle, in denen einer der Units leer ist, werden wir 2 übrig bleibenᵏ–2 Machbare Spaltungen. Beachten Sie als nächstes, dass wir uns nicht um die Reihenfolge der Units kümmern – Spaltungen wie {{A, B}, {C}} und {{C}, {a, b}} sind äquivalent. Dies senkt die Anzahl der eindeutigen Kombinationen in zwei Hälften, was zu einer endgültigen Anzahl von (2) führtᵏ–2)/2 Iterationen. Für unser oben genannter Spielzeugbeispiel mit Ok = 5 Kyrillische Buchstaben, diese Zahl ist 15. Aber wann Ok = 20Es Luftballons auf 524.287 Kombinationen – genug, um das DT -Coaching erheblich zu verlangsamen.

Die mittlere Zielcodierung löst das Effizienzproblem

Was wäre, wenn man den Suchraum von (2) reduzieren könnteᵏ–2)/2 zu etwas überschaubarer – ohne die optimale Spaltung zu verlieren? Es stellt sich heraus, dass dies in der Tat möglich ist. Man kann theoretisch zeigen, dass die mittlere Zielcodierung diese Reduzierung ermöglicht (3). Wenn die Kategorien in der Reihenfolge ihrer MTE -Werte angeordnet sind und nur aufteilt, die diese Reihenfolge respektieren, werden die optimalen Cut up – gemäß Gini -Verunreinigung für die Klassifizierung oder mittlerer quadratischer Fehler für die Regression – unter ihnen sein. Es gibt genau Ok-1 Solche Spaltungen, eine dramatische Reduktion im Vergleich zu (2ᵏ–2)/2. Der Pseudocode für MTE ist unten.

# ----------  Imply-target encoding ----------
FUNCTION MeanTargetEncode(desk):
    category_means = common(Worth) for every Class in desk      # Class → imply(Worth)
    encoded_column = lookup(desk.Class, category_means)         # exchange label with imply
    RETURN encoded_column

Experiment

Ich werde die theoretischen Ableitungen, die die oben genannten Ansprüche stützen, nicht wiederholen. Stattdessen habe ich ein Experiment entworfen, um sie empirisch zu validieren und ein Gefühl für die Effizienzgewinne zu erhalten, die von MTE gegenüber der nativen Partitionierung erzielt wurden, die alle möglichen Spaltungen umfassend iteriert. Im Folgenden erkläre ich den Datengenerierungsprozess und den Experiment -Setup.

Daten

Um synthetische Daten für das Experiment zu generieren, habe ich eine einfache Funktion verwendet, die einen Zwei-Spalt-Datensatz erstellt. Die erste Spalte enthält N unterschiedliche kategoriale Ebenen, jeweils wiederholt M mal, was zu insgesamt führt N × m Reihen. Die zweite Spalte repräsentiert die Zielvariable und kann je nach Eingabeparameter entweder binär oder kontinuierlich sein. Unten finden Sie den Pseudocode für diese Funktion.

# ----------  Artificial-dataset generator ----------
FUNCTION GenerateData(num_categories, rows_per_cat, target_type='binary'):
    total_rows = num_categories * rows_per_cat
    classes = ('Category_' + i for i in 1..num_categories)
    category_col = repeat_each(classes, rows_per_cat)

    IF target_type == 'steady':
        target_col = random_floats(0, 1, total_rows)
    ELSE:
        target_col = random_ints(0, 1, total_rows)

    RETURN DataFrame{ 'Class': category_col,
                      'Worth'   : target_col }

Experiment -Setup

Der experiment Die Funktion übernimmt eine Liste von Kardinalitäten und ein Spaltkriterium – entweder Gini -Verunreinigungen oder mittlerer quadratischer Fehler, abhängig vom Zieltyp. Für jede kategoriale Function-Kardinalität in der Liste generiert es 100 Datensätze und vergleicht zwei Strategien: eine erschöpfende Bewertung aller möglichen Kategorienaufteilungen und der eingeschränkten, mTE-informierten Bestellung. Es misst die Laufzeit jeder Methode und prüft, ob beide Ansätze den gleichen optimalen Cut up -Rating erzeugen. Die Funktion gibt die Anzahl der Übereinstimmungsfälle zusammen mit durchschnittlichen Laufzeiten zurück. Der Pseudocode ist unten angegeben.

# ----------  Cut up comparability experiment ----------
FUNCTION RunExperiment(list_num_categories, splitting_criterion):
    outcomes = ()

    FOR okay IN list_num_categories:
        times_all = ()
        times_ord = ()

        REPEAT 100 instances:
            df = GenerateDataset(okay, 100)

            t0 = now()
            s_all = MinScore(df, AllSplits, splitting_criterion)
            t1 = now()

            t2 = now()
            s_ord = MinScore(df, MTEOrderedSplits, splitting_criterion)
            t3 = now()

            times_all.append(t1 - t0)
            times_ord.append(t3 - t2)

            IF spherical(s_all,10) != spherical(s_ord,10):
                PRINT "Discrepancy at okay=", okay

        outcomes.append({
            'okay': okay,
            'avg_time_all': imply(times_all),
            'avg_time_ord': imply(times_ord)
        })

    RETURN DataFrame(outcomes)

Ergebnisse

Sie können mein Wort dafür nehmen oder das Experiment wiederholen (Github) – aber die optimalen Cut up -Scores beider Ansätze stimmten immer überein, genau wie die Theorie vorhersagt. Die folgende Abbildung zeigt die Zeit, die für die Bewertung von Splits als Funktion der Anzahl der Kategorien erforderlich ist. Die vertikale Achse befindet sich auf einer logarithmischen Skala. Die Linie, die eine ausführliche Bewertung darstellt, erscheint in diesen Koordinaten linear, was bedeutet, dass die Laufzeit exponentiell mit der Anzahl der Kategorien wächst – was die zuvor diskutierte theoretische Komplexität bestätigt. Bereits in 12 Kategorien (in einem Datensatz mit 1.200 Zeilen) dauert die Überprüfung aller möglichen Spaltungen etwa eine Sekunde-drei Größenordnungen langsamer als der MTE-basierte Ansatz, der den gleichen optimalen Cut up ergibt.

Binäres Ziel – Gini -Unreinheit. Bild erstellt vom Autor

Abschluss

Entscheidungsbäume können kategoriale Daten nativ verarbeiten, aber diese Fähigkeit erfolgt zu einer Rechenkosten, wenn die Kategorie zählt. Die mittlere Zielcodierung bietet eine prinzipielle Abkürzung, wodurch die Anzahl der Kandidatenaufteilungen drastisch verringert wird, ohne das Ergebnis zu beeinträchtigen. Unser Experiment bestätigt die Theorie: MTE-basierte Order findet den gleichen optimalen Cut up, aber exponentiell schneller.

Zum Zeitpunkt des Schreibens, scikit-learn unterstützt kategoriale Merkmale nicht direkt. Was denkst du additionally – wenn Sie die Daten mit MTE vorab zusammenarbeiten, entspricht der resultierende Entscheidungsbaum einem, das von einem Lernenden erstellt wurde, der kategoriale Merkmale nativ übernimmt?

Referenzen

(1) Ein Benchmark und eine Taxonomie kategorischer Encoder. Auf Knowledge Science. https://towardsdatascience.com/a-benchmark-and-taxonomy-of-categorical-coder-9b7a0dc47a8c/

(2) Bergbauregeln aus Daten. Auf Knowledge Science. https://towardsdatascience.com/mining-rules-from-data

(3) Hastie, Trevor, Tibshirani, Robert und Friedman, Jerome. Die Elemente des statistischen Lernens: Knowledge Mining, Inferenz und Vorhersage. Vol. 2. New York: Springer, 2009.

[ad_2]

]]>
http://chatgpz.de/machine-learning/entscheidungsbaeume-verarbeiten-kategoriale-daten-nativ/feed/ 0 9802
Mit DuckDB können Sie Milliarden von Zeilen mit SQL in wenigen Minuten verarbeiten http://chatgpz.de/machine-learning/mit-duckdb-koennen-sie-milliarden-von-zeilen-mit-sql-in-wenigen-minuten-verarbeiten/ http://chatgpz.de/machine-learning/mit-duckdb-koennen-sie-milliarden-von-zeilen-mit-sql-in-wenigen-minuten-verarbeiten/#respond Mon, 23 Dec 2024 11:07:51 +0000 http://chatgpz.de/machine-learning/mit-duckdb-koennen-sie-milliarden-von-zeilen-mit-sql-in-wenigen-minuten-verarbeiten/ [ad_1]

Analysieren Sie riesige Datensätze direkt im Speicher – schneller als je zuvor

Foto von Daniele Franchi An Unsplash

In diesem Projekt werden wir verarbeiten riesige Datensätze indem sie direkt in den Speicher geladen werden, was eine schnellere Analyse als mit herkömmlichen Methoden ermöglicht.

Durch Hebelwirkung In-Reminiscence-VerarbeitungWir können große Datenmengen effizient verarbeiten und schnell und effektiv aussagekräftige Erkenntnisse gewinnen.

Während die Geodatenanalyse ein zentraler Schwerpunkt ist, sind die Hauptziele des Projekts:

  • Beherrschen groß angelegte Datenmanipulation
  • Bewerben SQL-basierte Analysetechniken
  • Erkundung leistungsstarker Instruments für In-Reminiscence-Verarbeitung

Das Projekt integriert diese Konzepte anhand von Geodaten als Beispiel aus der Praxis.

Am Ende werden Sie verstehen, wie man große Datenmengen im Speicher verarbeitet, und sich so wertvolle Fähigkeiten für zukünftige Projekte aneignen.

[ad_2]

]]>
http://chatgpz.de/machine-learning/mit-duckdb-koennen-sie-milliarden-von-zeilen-mit-sql-in-wenigen-minuten-verarbeiten/feed/ 0 6055
Multimodales RAG: Verarbeiten Sie jeden Dateityp mit KI | von Shaw Talebi http://chatgpz.de/machine-learning/multimodales-rag-verarbeiten-sie-jeden-dateityp-mit-ki-von-shaw-talebi/ http://chatgpz.de/machine-learning/multimodales-rag-verarbeiten-sie-jeden-dateityp-mit-ki-von-shaw-talebi/#respond Fri, 06 Dec 2024 04:15:14 +0000 https://chatgpz.de/machine-learning/multimodales-rag-verarbeiten-sie-jeden-dateityp-mit-ki-von-shaw-talebi/ [ad_1]

Importe und Datenladen

Wir beginnen mit dem Import einiger praktischer Bibliotheken und Module.

import json
from transformers import CLIPProcessor, CLIPTextModelWithProjection
from torch import load, matmul, argsort
from torch.nn.useful import softmax

Als Nächstes importieren wir Textual content- und Bildblöcke aus Multimodale LLMs Und Multimodale Einbettungen Blogbeiträge. Diese werden in .json-Dateien gespeichert, die als Liste von Wörterbüchern in Python geladen werden können.

# load textual content chunks
with open('knowledge/text_content.json', 'r', encoding='utf-8') as f:
text_content_list = json.load(f)

# load photos
with open('knowledge/image_content.json', 'r', encoding='utf-8') as f:
image_content_list = json.load(f)

Obwohl ich den Datenvorbereitungsprozess hier nicht besprechen werde, befindet sich der von mir verwendete Code auf der GitHub-Repo.

Wir laden auch die multimodalen Einbettungen (von CLIP) für jedes Ingredient in text_content_list Und image_content_list. Diese werden als Pytorch-Tensoren gespeichert.

# load embeddings
text_embeddings = load('knowledge/text_embeddings.pt', weights_only=True)
image_embeddings = load('knowledge/image_embeddings.pt', weights_only=True)

print(text_embeddings.form)
print(image_embeddings.form)

# >> torch.Measurement((86, 512))
# >> torch.Measurement((17, 512))

Wenn wir die Type dieser Tensoren ausdrucken, sehen wir, dass sie durch 512-dimensionale Einbettungen dargestellt werden. Und wir haben 86 Textblöcke und 17 Bilder.

Multimodale Suche

Nachdem unsere Wissensdatenbank geladen ist, können wir nun eine Abfrage für die Vektorsuche definieren. Dies besteht aus der Übersetzung einer Eingabeabfrage in eine Einbettung mithilfe von CLIP. Dies machen wir analog zu den Beispielen aus dem vorheriger Beitrag.

# question
question = "What's CLIP's contrastive loss operate?"

# embed question (4 steps)
# 1) load mannequin
mannequin = CLIPTextModelWithProjection.from_pretrained("openai/clip-vit-base-patch16")
# 2) load knowledge processor
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch16")
# 3) pre-process textual content
inputs = processor(textual content=(textual content), return_tensors="pt", padding=True)
# 4) compute embeddings with CLIP
outputs = mannequin(**inputs)

# extract embedding
query_embed = outputs.text_embeds
print(query_embed.form)

# >> torch.Measurement((1, 512))

Wenn wir die Type ausdrucken, sehen wir, dass wir einen einzelnen Vektor haben, der die Abfrage darstellt.

Um eine Vektorsuche in der Wissensdatenbank durchzuführen, müssen wir Folgendes tun.

  1. Berechnen Sie Ähnlichkeiten zwischen der Abfrageeinbettung und allen Textual content- und Bildeinbettungen.
  2. Skalieren Sie die Ähnlichkeiten über die Softmax-Funktion neu, sodass sie von 0 bis 1 reichen.
  3. Sortieren Sie die skalierten Ähnlichkeiten und geben Sie die besten okay Ergebnisse zurück.
  4. Filtern Sie abschließend die Ergebnisse, um nur Elemente oberhalb eines vordefinierten Ähnlichkeitsschwellenwerts beizubehalten.

So sieht das im Code für die Textblöcke aus.

# outline okay and simiarlity threshold
okay = 5
threshold = 0.05

# multimodal search over articles
text_similarities = matmul(query_embed, text_embeddings.T)

# rescale similarities by way of softmax
temp=0.25
text_scores = softmax(text_similarities/temp, dim=1)

# return prime okay filtered textual content outcomes
isorted_scores = argsort(text_scores, descending=True)(0)
sorted_scores = text_scores(0)(isorted_scores)

itop_k_filtered = (idx.merchandise()
for idx, rating in zip(isorted_scores, sorted_scores)
if rating.merchandise() >= threshold)(:okay)
top_k = (text_content_list(i) for i in itop_k_filtered)

print(top_k)

# prime okay outcomes

({'article_title': 'Multimodal Embeddings: An Introduction',
'part': 'Contrastive Studying',
'textual content': 'Two key points of CL contribute to its effectiveness'})

Oben sehen wir die besten Textergebnisse. Beachten Sie, dass wir jedoch nur einen Artikel haben okay=5. Dies liegt daran, dass die 2. bis 5. Elemente unter dem Schwellenwert von 0,1 lagen.

Interessanterweise scheint dieser Artikel für unsere erste Anfrage nicht hilfreich zu sein „Was ist die Kontrastverlustfunktion von CLIP?“ Dies unterstreicht eine der größten Herausforderungen der Vektorsuche: Elemente, die einer bestimmten Anfrage ähneln, helfen möglicherweise nicht unbedingt bei der Beantwortung dieser Frage.

Eine Möglichkeit, dieses Downside abzumildern, besteht darin, unsere Suchergebnisse durch Erhöhen weniger streng einzuschränken okay und die Ähnlichkeit verringern Schwelleund hoffe dann, dass der LLM herausfinden kann, was hilfreich ist und was nicht.

Dazu packe ich zunächst die Schritte der Vektorsuche in eine Python-Funktion.

def similarity_search(query_embed, target_embeddings, content_list, 
okay=5, threshold=0.05, temperature=0.5):
"""
Carry out similarity search over embeddings and return prime okay outcomes.
"""
# Calculate similarities
similarities = torch.matmul(query_embed, target_embeddings.T)

# Rescale similarities by way of softmax
scores = torch.nn.useful.softmax(similarities/temperature, dim=1)

# Get sorted indices and scores
sorted_indices = scores.argsort(descending=True)(0)
sorted_scores = scores(0)(sorted_indices)

# Filter by threshold and get prime okay
filtered_indices = (
idx.merchandise() for idx, rating in zip(sorted_indices, sorted_scores)
if rating.merchandise() >= threshold
)(:okay)

# Get corresponding content material gadgets and scores
top_results = (content_list(i) for i in filtered_indices)
result_scores = (scores(0)(i).merchandise() for i in filtered_indices)

return top_results, result_scores

Legen Sie dann umfassendere Suchparameter fest.

# search over textual content chunks
text_results, text_scores = similarity_search(query_embed, text_embeddings,
text_content_list, okay=15, threshold=0.01, temperature=0.25)

# search over photos
image_results, image_scores = similarity_search(query_embed, image_embeddings,
image_content_list, okay=5, threshold=0.25, temperature=0.5)

Dies führt zu 15 Textergebnissen und 1 Bildergebnis.

1 - Two key points of CL contribute to its effectiveness
2 - To make a category prediction, we should extract the picture logits and consider
which class corresponds to the utmost.
3 - Subsequent, we are able to import a model of the clip mannequin and its related knowledge
processor. Observe: the processor handles tokenizing enter textual content and picture
preparation.
4 - The fundamental thought behind utilizing CLIP for 0-shot picture classification is to
move a picture into the mannequin together with a set of attainable class labels. Then,
a classification may be made by evaluating which textual content enter is most just like
the enter picture.
5 - We will then match the perfect picture to the enter textual content by extracting the textual content
logits and evaluating the picture similar to the utmost.
6 - The code for these examples is freely obtainable on the GitHub repository.
7 - We see that (once more) the mannequin nailed this straightforward instance. However let’s attempt
some trickier examples.
8 - Subsequent, we’ll preprocess the picture/textual content inputs and move them into the mannequin.
9 - One other sensible software of fashions like CLIP is multimodal RAG, which
consists of the automated retrieval of multimodal context to an LLM. Within the
subsequent article of this sequence, we are going to see how this works beneath the hood and
assessment a concrete instance.
10 - One other software of CLIP is actually the inverse of Use Case 1.
Quite than figuring out which textual content label matches an enter picture, we are able to
consider which picture (in a set) finest matches a textual content enter (i.e. question)—in
different phrases, performing a search over photos.
11 - This has sparked efforts towards increasing LLM performance to incorporate
a number of modalities.
12 - GPT-4o — Enter: textual content, photos, and audio. Output: textual content.FLUX — Enter: textual content.
Output: photos.Suno — Enter: textual content. Output: audio.
13 - The usual strategy to aligning disparate embedding areas is
contrastive studying (CL). A key instinct of CL is to symbolize totally different
views of the identical data equally (5).
14 - Whereas the mannequin is much less assured about this prediction with a 54.64%
chance, it appropriately implies that the picture will not be a meme.
15 - (8) Mini-Omni2: In direction of Open-source GPT-4o with Imaginative and prescient, Speech and Duplex
Capabilities
Bildsuchergebnis.

Aufforderndes MLLM

Obwohl die meisten dieser Textelementergebnisse für unsere Abfrage nicht hilfreich zu sein scheinen, ist das Bildergebnis genau das, wonach wir suchen. Lassen Sie uns dennoch anhand dieser Suchergebnisse sehen, wie LLaMA 3.2 Imaginative and prescient auf diese Anfrage reagiert.

Wir werden die Suchergebnisse zunächst als intestine formatierte Zeichenfolgen strukturieren.

text_context = ""
for textual content in text_results:
if text_results:
text_context = text_context + "**Article title:** "
+ textual content('article_title') + "n"
text_context = text_context + "**Part:** "
+ textual content('part') + "n"
text_context = text_context + "**Snippet:** "
+ textual content('textual content') + "nn"
image_context = ""
for picture in image_results:
if image_results:
image_context = image_context + "**Article title:** "
+ picture('article_title') + "n"
image_context = image_context + "**Part:** "
+ picture('part') + "n"
image_context = image_context + "**Picture Path:** "
+ picture('image_path') + "n"
image_context = image_context + "**Picture Caption:** "
+ picture('caption') + "nn"

Beachten Sie die Metadaten, die jedem Textual content- und Bildelement beiliegen. Dies wird dem LLaMA helfen, den Kontext des Inhalts besser zu verstehen.

Als nächstes verschachteln wir die Textual content- und Bildergebnisse zu einer Eingabeaufforderung.

# assemble immediate template
immediate = f"""Given the question "{question}" and the next related snippets:

{text_context}
{image_context}

Please present a concise and correct reply to the question, incorporating
related data from the offered snippets the place attainable.

"""

Die letzte Eingabeaufforderung ist ziemlich lang, daher werde ich sie hier nicht abdrucken. Es wird jedoch vollständig im angezeigt Beispiel-Notizbuch auf GitHub.

Endlich können wir es verwenden Ollama um diese Aufforderung an LLaMA 3.2 Imaginative and prescient weiterzuleiten.

ollama.pull('llama3.2-vision')

response = ollama.chat(
mannequin='llama3.2-vision',
messages=({
'function': 'consumer',
'content material': immediate,
'photos': (picture("image_path") for picture in image_results)
})
)

print(response('message')('content material'))

The picture depicts a contrastive loss operate for aligning textual content and picture 
representations in multimodal fashions. The operate is designed to reduce the
distinction between the similarity of constructive pairs (text-image) and unfavourable
pairs (text-text or image-image). This loss operate is often utilized in CLIP,
which stands for Contrastive Language-Picture Pre-training.

**Key Parts:**

* **Optimistic Pairs:** Textual content-image pairs the place the textual content describes a picture.
* **Damaging Pairs:** Textual content-text or image-image pairs that don't belong to
the identical class.
* **Contrastive Loss Operate:** Calculates the distinction between constructive
and unfavourable pairs' similarities.

**The way it Works:**

1. **Textual content-Picture Embeddings:** Generate embeddings for each textual content and pictures
utilizing a multimodal encoder (e.g., CLIP).
2. **Optimistic Pair Similarity:** Calculate the similarity rating between every
text-image pair.
3. **Damaging Pair Similarity:** Calculate the similarity scores between all
unfavourable pairs.
4. **Contrastive Loss Calculation:** Compute the contrastive loss by
minimizing the distinction between constructive and unfavourable pairs' similarities.

**Advantages:**

* **Multimodal Alignment:** Aligns textual content and picture representations for higher
understanding of visible content material from textual content descriptions.
* **Improved Efficiency:** Enhances efficiency in downstream duties like
picture classification, retrieval, and technology.

Das Modell erkennt richtig, dass das Bild die benötigten Informationen enthält und erklärt die allgemeine Instinct seiner Funktionsweise. Allerdings ist es missversteht die Bedeutung von positiven und negativen Paarendenkend, dass ein negatives Paar einem Paar derselben Modalität entspricht.

Während wir die Implementierungsdetails Schritt für Schritt durchgingen, habe ich hier mithilfe von Gradio alles in eine schöne Benutzeroberfläche gepackt Notizbuch im GitHub-Repo.

Multimodale RAG-Systeme können in verschiedenen Formaten gespeichertes Wissen synthetisieren und so die Möglichkeiten von KI erweitern. Hier haben wir drei einfache Strategien zur Entwicklung eines solchen Methods besprochen und dann eine Beispielimplementierung eines multimodalen Weblog-QS-Assistenten gesehen.

Obwohl das Beispiel für diese Demonstration intestine genug funktionierte, gibt es klare Einschränkungen beim Suchvorgang. Einige Techniken, die dies verbessern können, umfassen die Verwendung von a Reranker zur Verfeinerung der Ähnlichkeitssuche Ergebnisse und zur Verbesserung der Suchqualität über fein abgestimmte multimodale Einbettungen.

Wenn Sie zukünftige Beiträge zu diesen Themen sehen möchten, lassen Sie es mich in den Kommentaren wissen 🙂

Mehr zu multimodalen Modellen 👇

Shaw Talebi

Multimodale KI

[ad_2]

]]>
http://chatgpz.de/machine-learning/multimodales-rag-verarbeiten-sie-jeden-dateityp-mit-ki-von-shaw-talebi/feed/ 0 5667
Maskierte Arrays in NumPy zum Verarbeiten fehlender Daten http://chatgpz.de/data-analytics/maskierte-arrays-in-numpy-zum-verarbeiten-fehlender-daten/ http://chatgpz.de/data-analytics/maskierte-arrays-in-numpy-zum-verarbeiten-fehlender-daten/#respond Sat, 10 Aug 2024 23:34:44 +0000 http://chatgpz.de/data-analytics/maskierte-arrays-in-numpy-zum-verarbeiten-fehlender-daten/ [ad_1]

Maskierte Arrays in NumPy zum Verarbeiten fehlender DatenMaskierte Arrays in NumPy zum Verarbeiten fehlender Daten
Bild vom Autor

Stellen Sie sich vor, Sie versuchen, ein Puzzle zu lösen, bei dem Teile fehlen. Das kann frustrierend sein, nicht wahr? Dies ist ein häufiges Szenario beim Umgang mit unvollständigen Datensätzen. Maskierte Arrays in NumPy sind spezielle Array-Strukturen, mit denen Sie fehlende oder ungültige Daten effizient verarbeiten können. Sie sind besonders nützlich in Szenarien, in denen Sie Berechnungen an Datensätzen mit unzuverlässigen Einträgen durchführen müssen.

Ein maskiertes Array ist im Wesentlichen eine Kombination aus zwei Arrays:

  • Datenarray: Das primäre Array, das die tatsächlichen Datenwerte enthält.
  • Masken-Array: Ein boolesches Array mit derselben Kind wie das Datenarray, wobei jedes Factor angibt, ob das entsprechende Datenelement gültig oder maskiert (ungültig/fehlend) ist.

Datenarray

Das Datenarray ist die Kernkomponente eines maskierten Arrays und enthält die tatsächlichen Datenwerte, die Sie analysieren oder bearbeiten möchten. Dieses Array kann beliebige numerische oder kategorische Daten enthalten, genau wie ein Commonplace-NumPy-Array. Hier sind einige wichtige Punkte, die Sie beachten sollten:

  • Lagerung: Das Datenarray speichert die Werte, mit denen Sie arbeiten müssen, einschließlich gültiger und ungültiger Einträge (wie „NaN“ oder bestimmte Werte, die fehlende Daten darstellen).
  • Operationen: Beim Ausführen von Operationen verwendet NumPy das Datenarray zum Berechnen der Ergebnisse, berücksichtigt jedoch das Maskenarray, um zu bestimmen, welche Elemente ein- oder ausgeschlossen werden sollen.
  • Kompatibilität: Das Datenarray in einem maskierten Array unterstützt alle Standardfunktionen von NumPy, sodass Sie problemlos zwischen regulären und maskierten Arrays wechseln können, ohne Ihre vorhandene Codebasis wesentlich zu verändern.

Beispiel:

import numpy as np

information = np.array((1.0, 2.0, np.nan, 4.0, 5.0))
masked_array = np.ma.array(information)
print(masked_array.information)  # Output: ( 1.  2. nan  4.  5.)

Masken-Array

Das Masken-Array ist ein Boolean-Array mit der gleichen Kind wie das Daten-Array. Jedes Factor im Masken-Array entspricht einem Factor im Daten-Array und gibt an, ob dieses Factor gültig ist (FALSCH) oder maskiert (WAHR). Hier sind einige detaillierte Punkte:

  • Struktur: Das Masken-Array wird mit der gleichen Kind wie das Daten-Array erstellt, um sicherzustellen, dass jeder Datenpunkt einen entsprechenden Maskenwert hat.
  • Angabe ungültiger Daten: A WAHR Der Wert im Maskenarray markiert den entsprechenden Datenpunkt als ungültig oder fehlend, während ein FALSCH Wert gibt gültige Daten an. Dadurch kann NumPy ungültige Datenpunkte während der Berechnung ignorieren oder ausschließen.
  • Automatische Maskierung: NumPy bietet Funktionen zum automatischen Erstellen von Masken-Arrays basierend auf bestimmten Bedingungen (z. B. np.ma.masked_invalid() maskieren NaN Werte).

Beispiel:

import numpy as np

information = np.array((1.0, 2.0, np.nan, 4.0, 5.0))
masks = np.isnan(information)  # Create a masks the place NaN values are True
masked_array = np.ma.array(information, masks=masks)
print(masked_array.masks)  # Output: (False False  True False False)

Die Stärke maskierter Arrays liegt in der Beziehung zwischen den Daten- und Maskenarrays. Wenn Sie Operationen an einem maskierten Array durchführen, berücksichtigt NumPy beide Arrays, um sicherzustellen, dass die Berechnungen nur auf gültigen Daten basieren.

Vorteile maskierter Arrays

Maskierte Arrays in NumPy bieten mehrere Vorteile, insbesondere beim Umgang mit Datensätzen, die fehlende oder ungültige Daten enthalten, darunter:

  1. Effizienter Umgang mit fehlenden Daten: Mit maskierten Arrays können Sie ungültige oder fehlende Daten, wie z. B. NaNs, einfach markieren und sie bei Berechnungen automatisch verarbeiten. Operationen werden nur mit gültigen Daten ausgeführt, um sicherzustellen, dass fehlende oder ungültige Einträge die Ergebnisse nicht verfälschen.
  2. Vereinfachte Datenbereinigung: Funktionen wie numpy.ma.masked_invalid() kann häufige ungültige Werte (z. B. NaNs oder Unendlichkeiten) automatisch maskieren, ohne dass zusätzlicher Code zum manuellen Identifizieren und Verarbeiten dieser Werte erforderlich ist. Sie können benutzerdefinierte Masken basierend auf bestimmten Kriterien definieren, was versatile Datenbereinigungsstrategien ermöglicht.
  3. Nahtlose Integration mit NumPy-Funktionen: Maskierte Arrays funktionieren mit den meisten Standardfunktionen und -operationen von NumPy. Das bedeutet, dass Sie vertraute NumPy-Methoden verwenden können, ohne maskierte Werte manuell auszuschließen oder vorzuverarbeiten.
  4. Verbesserte Genauigkeit bei Berechnungen: Bei der Durchführung von Berechnungen (z. B. Mittelwert, Summe, Standardabweichung) werden maskierte Werte automatisch von der Berechnung ausgeschlossen, was zu genaueren und aussagekräftigeren Ergebnissen führt.
  5. Verbesserte Datenvisualisierung: Beim Visualisieren von Daten stellen maskierte Arrays sicher, dass ungültige oder fehlende Werte nicht dargestellt werden, was zu klareren und genaueren visuellen Darstellungen führt. Sie können nur die gültigen Daten darstellen, um Unordnung zu vermeiden und die Interpretierbarkeit von Grafiken und Diagrammen zu verbessern.

Verwenden maskierter Arrays zum Verarbeiten fehlender Daten in NumPy

In diesem Abschnitt wird gezeigt, wie man maskierte Arrays verwendet, um fehlende Daten in Numpy zu verarbeiten. Schauen wir uns zunächst ein einfaches Beispiel an:

import numpy as np

# Knowledge with some lacking values represented by -999
information = np.array((10, 20, -999, 30, -999, 40))

# Create a masks the place -999 is taken into account as lacking information
masks = (information == -999)

# Create a masked array utilizing the information and masks
masked_array = np.ma.array(information, masks=masks)

# Calculate the imply, ignoring masked values
mean_value = masked_array.imply()
print(mean_value)

Ausgabe:
25,0

Erläuterung:

  • Datenerstellung: information ist ein Array von Ganzzahlen, wobei -999 stellt fehlende Werte dar.
  • Maskenerstellung: masks ist ein boolesches Array, das Positionen markiert mit -999 als WAHR (weist auf fehlende Daten hin).
  • Maskierte Array-Erstellung: np.ma.array(information, masks=masks) erstellt ein maskiertes Array und wendet die Maske an auf information.
  • Berechnung: masked_array.imply().
  • berechnet den Mittelwert und ignoriert dabei maskierte Werte (d. h. -999), was den Durchschnitt der verbleibenden gültigen Werte ergibt.

In diesem Beispiel wird der Mittelwert nur berechnet aus (10, 20, 30, 40)ausschließlich -999 Werte.

Sehen wir uns ein umfassenderes Beispiel an, bei dem maskierte Arrays verwendet werden, um fehlende Daten in einem größeren Datensatz zu verarbeiten. Wir verwenden ein Szenario mit einem Datensatz mit Temperaturmessungen von mehreren Sensoren über mehrere Tage hinweg. Der Datensatz enthält einige fehlende Werte aufgrund von Sensorfehlern.

Anwendungsfall: Analysieren von Temperaturdaten von mehreren Sensoren

Szenario: Sie haben Temperaturmesswerte von fünf Sensoren über zehn Tage. Einige Messwerte fehlen aufgrund von Sensorproblemen. Wir müssen die durchschnittliche Tagestemperatur berechnen und dabei die fehlenden Daten ignorieren.

Datensatz: Der Datensatz wird als 2D-NumPy-Array dargestellt, wobei Zeilen Tage und Spalten Sensoren darstellen. Fehlende Werte werden durch np.nan.

Folgende Schritte sind erforderlich:

  1. NumPy importieren: Für Array-Operationen und die Handhabung maskierter Arrays.
  2. Definieren Sie die Daten: Erstellen Sie ein 2D-Array von Temperaturmesswerten mit einigen fehlenden Werten.
  3. Erstellen einer Maske: Identifizieren Sie fehlende Werte (NaNs) im Datensatz.
  4. Maskierte Arrays erstellen: Wenden Sie die Maske an, um fehlende Werte zu behandeln.
  5. Tagesdurchschnitte berechnen Berechnen Sie die Durchschnittstemperatur für jeden Tag und ignorieren Sie fehlende Werte.
  6. Ausgabeergebnisse: Ergebnisse zur Analyse anzeigen.

Code:

import numpy as np

# Instance temperature readings from 5 sensors over 10 days
# Rows: days, Columns: sensors
temperature_data = np.array((
    (22.1, 21.5, np.nan, 23.0, 22.8),  # Day 1
    (20.3, np.nan, 22.0, 21.8, 23.1),  # Day 2
    (np.nan, 23.2, 21.7, 22.5, 22.0),  # Day 3
    (21.8, 22.0, np.nan, 21.5, np.nan),  # Day 4
    (22.5, 22.1, 21.9, 22.8, 23.0),  # Day 5
    (np.nan, 21.5, 22.0, np.nan, 22.7),  # Day 6
    (22.0, 22.5, 23.0, np.nan, 22.9),  # Day 7
    (21.7, np.nan, 22.3, 22.1, 21.8),  # Day 8
    (22.4, 21.9, np.nan, 22.6, 22.2),  # Day 9
    (23.0, 22.5, 21.8, np.nan, 22.0)   # Day 10
))

# Create a masks for lacking values (NaNs)
masks = np.isnan(temperature_data)

# Create a masked array
masked_data = np.ma.masked_array(temperature_data, masks=masks)

# Calculate the common temperature for every day, ignoring lacking values
daily_averages = masked_data.imply(axis=1)  # Axis 1 represents days

# Print the outcomes
for day, avg_temp in enumerate(daily_averages, begin=1):
    print(f"Day {day}: Common Temperature = {avg_temp:.2f} °C")

Ausgabe:

Maskierte Arrays Beispiel IIIMaskierte Arrays Beispiel III

Erläuterung:

  • NumPy importieren: Importieren Sie die NumPy Bibliothek, um ihre Funktionen zu nutzen.
  • Daten definieren: Erstellen Sie ein 2D-Array temperature_data wobei jede Zeile die Temperaturen von Sensoren an einem bestimmten Tag darstellt und einige Werte fehlen (np.nan).
  • Maske erstellen: Erzeugen Sie eine Boolesche Maske mit np.isnan(temperature_data) um fehlende Werte zu identifizieren (WAHR wo Werte sind np.nan).
  • Maskiertes Array erstellen: Verwenden np.ma.masked_array(temperature_data, masks=masks) erstellen masked_data. Dieses Array maskiert fehlende Werte, sodass sie bei Operationen ignoriert werden können.
  • Tägliche Durchschnittswerte berechnen: Berechnen Sie die Durchschnittstemperatur für jeden Tag mit .imply(axis=1). Hier, axis=1 bedeutet, den Mittelwert aller Sensoren für jeden Tag zu berechnen.
  • Ausgabeergebnisse: Drucken Sie die Durchschnittstemperatur für jeden Tag. Die maskierten Werte werden von der Berechnung ausgeschlossen, sodass genaue Tagesdurchschnitte entstehen.

Abschluss

In diesem Artikel haben wir das Konzept maskierter Arrays untersucht und wie sie genutzt werden können, um mit fehlenden Daten umzugehen. Wir haben die beiden Hauptkomponenten maskierter Arrays besprochen: das Datenarray, das die tatsächlichen Werte enthält, und das Maskenarray, das angibt, welche Werte gültig sind oder fehlen. Wir haben auch ihre Vorteile untersucht, darunter die effiziente Handhabung fehlender Daten, die nahtlose Integration mit NumPy-Funktionen und eine verbesserte Berechnungsgenauigkeit.

Wir haben die Verwendung maskierter Arrays anhand einfacher und komplexerer Beispiele demonstriert. Das erste Beispiel veranschaulichte den Umgang mit fehlenden Werten, die durch bestimmte Markierungen dargestellt werden, wie -999während das ausführlichere Beispiel zeigte, wie Temperaturdaten von mehreren Sensoren analysiert werden, wobei fehlende Werte durch np.nan. Beide Beispiele verdeutlichten die Fähigkeit maskierter Arrays, durch Ignorieren ungültiger Daten genaue Ergebnisse zu berechnen.

Weitere Informationen finden Sie in diesen beiden Ressourcen:

Shittu Olumide ist ein Softwareentwickler und technischer Autor, der mit Leidenschaft modernste Technologien nutzt, um überzeugende Geschichten zu schreiben, mit einem scharfen Auge für Particulars und einem Händchen für die Vereinfachung komplexer Konzepte. Sie finden Shittu auch auf Þjórsárdalur.



[ad_2]

]]>
http://chatgpz.de/data-analytics/maskierte-arrays-in-numpy-zum-verarbeiten-fehlender-daten/feed/ 0 3062