Txtaiのチュートリアルシリーズ



このチュートリアルシリーズはtxtai , AI動力セマンティック検索プラットフォームシリーズの各部分は完全に各記事を再現することができます対応するノートブックがあります.

紹介Txtai


txtai データを変換し、AIで動く意味の検索アプリケーションを構築するために、機械学習ワークフローを実行します.
伝統的な検索システムのキーワードを使用してデータを検索します.セマンティック検索アプリケーションは、自然言語の理解を持って、同じ意味を持っている結果を識別し、必ずしも同じキーワードではありません.
最新の機械学習モデルによって支持されて、データは検索(また、埋め込みとして知られている)のためにベクトル表現に変えられます.イノベーションは急速なペースで起こっている、モデルは、ドキュメント、オーディオ、画像などの概念を理解することができます.
以下は主要な機能の概要です.
  • 🔎 多重インデックスバックエンドによる大規模類似性探索Faiss , Annoy , Hnswlib )
  • 📄 テキストスニペット、ドキュメント、オーディオ、画像やビデオの埋め込みを作成します.変圧器と単語ベクトルをサポートします.
  • 💡 抽出質問応答,ゼロショットラベリング,転写,翻訳,要約およびテキスト抽出を実行する機械学習パイプライン
  • ↪️️ ビジネスロジックを集約するパイプラインに結合するワークフロー.TXTIプロセスは、マイクロサービスまたは完全なインデックスワークフローでありえます.
  • 🔗 API結合JavaScript , Java , Rust and Go
  • ☁️ コンテナ・オーケストレーションシステム(例えばKubernetes)で目立つ雲ネイティブ建築
  • アプリケーションは,類似性探索から複雑なnlp駆動データ抽出により構造化データベースを生成する.次のアプリケーションはTxtaiによって供給されます.

  • paperai - 医学/科学論文のためのAI動力文献発見とレビューエンジン

  • tldrstory - 見出しとストーリーテキストのAI Power理解

  • neuspo - 事実駆動、リアルタイムスポーツイベントとニュースサイト

  • codequestion - 端末から直接質問をコーディングする
  • TxtaiはPython 3.7 +で構築されています.Hugging Face Transformers , Sentence Transformers and FastAPI
    この記事では、Txtaiの概要と類似の検索を実行する方法を示します.

    依存関係のインストール


    インストールtxtai すべての依存関係.
    pip install txtai
    

    埋め込みインスタンスを作成する


    埋め込みのインスタンスはTxTaiの主なエントリポイントです.埋め込みメソッドは、テキストセクションをトークン化して変換するために使用されるメソッドを定義します.
    from txtai.embeddings import Embeddings
    
    # Create embeddings model, backed by sentence-transformers & transformers
    embeddings = Embeddings({"path": "sentence-transformers/nli-mpnet-base-v2"})
    

    類似性質問の実行


    埋め込み埋め込みインスタンスは、テキスト埋め込みを構築するために、基になるトランスモデルに依存します.Transformers埋め込みインスタンスを使用して、異なる概念のリストの類似検索を実行する方法を次の例に示します.
    data = ["US tops 5 million confirmed virus cases",
            "Canada's last fully intact ice shelf has suddenly collapsed, forming a Manhattan-sized iceberg",
            "Beijing mobilises invasion craft along coast as Taiwan tensions escalate",
            "The National Park Service warns against sacrificing slower friends in a bear attack",
            "Maine man wins $1M from $25 lottery ticket",
            "Make huge profits without work, earn up to $100,000 a day"]
    
    print("%-20s %s" % ("Query", "Best Match"))
    print("-" * 50)
    
    for query in ("feel good story", "climate change", "public health story", "war", "wildlife", "asia", "lucky", "dishonest junk"):
        # Get index of best section that best matches query
        uid = embeddings.similarity(query, data)[0][0]
    
        print("%-20s %s" % (query, data[uid]))
    
    Query                Best Match
    --------------------------------------------------
    feel good story      Maine man wins $1M from $25 lottery ticket
    climate change       Canada's last fully intact ice shelf has suddenly collapsed, forming a Manhattan-sized iceberg
    health               US tops 5 million confirmed virus cases
    war                  Beijing mobilises invasion craft along coast as Taiwan tensions escalate
    wildlife             The National Park Service warns against sacrificing slower friends in a bear attack
    asia                 Beijing mobilises invasion craft along coast as Taiwan tensions escalate
    lucky                Maine man wins $1M from $25 lottery ticket
    dishonest junk       Make huge profits without work, earn up to $100,000 a day
    
    上記の例では、ほとんどすべてのクエリに対して、実際のテキストはテキストセクションのリストに格納されていません.これは、トークンベースの検索上のトランスモデルの真のパワーです.あなたが箱から出るものは🔥🔥🔥!

    埋め込みインデックスの作成


    テキストの小さなリストのために、上記の方法は、働きます.しかし、ドキュメントのより大きいリポジトリのために、それはtokenizeするのに意味をなさないで、各々の問合せに埋込みに変わる.TXTIは、パフォーマンスを象徴的に改善する事前計算インデックスを構築するサポートしています.
    前の例に基づいて、次の例では、Indexメソッドを実行してテキスト埋め込みをビルドして保存します.この場合、クエリのみが各検索の埋め込みベクトルに変換されます.
    # Create an index for the list of text
    embeddings.index([(uid, text, None) for uid, text in enumerate(data)])
    
    print("%-20s %s" % ("Query", "Best Match"))
    print("-" * 50)
    
    # Run an embeddings search for each query
    for query in ("feel good story", "climate change", "public health story", "war", "wildlife", "asia", "lucky", "dishonest junk"):
        # Extract uid of first result
        # search result format: (uid, score)
        uid = embeddings.search(query, 1)[0][0]
    
        # Print text
        print("%-20s %s" % (query, data[uid]))
    
    Query                Best Match
    --------------------------------------------------
    feel good story      Maine man wins $1M from $25 lottery ticket
    climate change       Canada's last fully intact ice shelf has suddenly collapsed, forming a Manhattan-sized iceberg
    health               US tops 5 million confirmed virus cases
    war                  Beijing mobilises invasion craft along coast as Taiwan tensions escalate
    wildlife             The National Park Service warns against sacrificing slower friends in a bear attack
    asia                 Beijing mobilises invasion craft along coast as Taiwan tensions escalate
    lucky                Maine man wins $1M from $25 lottery ticket
    dishonest junk       Make huge profits without work, earn up to $100,000 a day
    

    埋め込み/ロード


    埋め込みインデックスをディスクに保存し、再ロードすることができます.このとき、インデックスはインクリメンタルに作成されません、インデックスは新しいデータを組み込むために完全な再構築を必要とします.しかし、その増強はbacklogにあります.
    embeddings.save("index")
    
    embeddings = Embeddings()
    embeddings.load("index")
    
    uid = embeddings.search("climate change", 1)[0][0]
    print(data[uid])
    
    Canada's last fully intact ice shelf has suddenly collapsed, forming a Manhattan-sized iceberg
    
    ls index
    
    config  embeddings
    

    埋め込み/更新


    更新と削除はインデックスを埋め込むためにサポートされます.upsert操作は新しいデータを挿入し、既存のデータを更新します
    次のセクションではクエリを実行し、トップの結果を変更する値を更新し、最終的に更新された値を削除して元のクエリ結果に戻します.
    # Run initial query
    uid = embeddings.search("feel good story", 1)[0][0]
    print("Initial: ", data[uid])
    
    # Create a copy of data to modify
    udata = data.copy()
    
    # Update data
    udata[0] = "See it: baby panda born"
    embeddings.upsert([(0, udata[0], None)])
    
    uid = embeddings.search("feel good story", 1)[0][0]
    print("After update: ", udata[uid])
    
    # Remove record just added from index
    embeddings.delete([0])
    
    # Ensure value matches previous value
    uid = embeddings.search("feel good story", 1)[0][0]
    print("After delete: ", udata[uid])
    
    Initial:  Maine man wins $1M from $25 lottery ticket
    After update:  See it: baby panda born
    After delete:  Maine man wins $1M from $25 lottery ticket
    

    コンテンツの埋め込みインデックス


    この点まで、すべての例は、入力テキストを読み出すために原作のデータ配列を参照している.あなたが文書の何百万を持っているならば、これはデモのためにうまくいきます、しかし、何?この場合、テキストはIDを使用して外部データストアから取得する必要があります.
    Txtai 4.0インデックスの横にコンテンツを格納するに関連する新機能の数を追加します.これらの機能Txtaiでエキサイティングな可能性の数を開く!
    ドキュメント・テキスト、付加メタデータおよび付加オブジェクトは、格納されて、インデックス媒介者と並んで右の検索されることができる.
    # Create embeddings index with content enabled. The default behavior is to only store indexed vectors.
    embeddings = Embeddings({"path": "sentence-transformers/nli-mpnet-base-v2", "content": True, "objects": True})
    
    # Create an index for the list of text
    embeddings.index([(uid, text, None) for uid, text in enumerate(data)])
    
    print(embeddings.search("feel good story", 1)[0]["text"])
    
    Maine man wins $1M from $25 lottery ticket
    
    上記の唯一の変更は、コンテンツフラグをtrueに設定することです.これにより、インデックスと一緒にテキストとメタデータの内容を格納できます.テキストがクエリ結果から右に引っ張られる方法に注意してください!
    メタデータを加えましょう.

    SQLクエリ


    コンテンツが有効になっている場合は、全体の辞書が格納され、クエリすることができます.類似性クエリに加えて、TXTIはSQLクエリを受け入れます.これにより、データベースバックエンドに格納された類似インデックスとコンテンツの両方を使用してクエリを組み合わせます.
    # Create an index for the list of text
    embeddings.index([(uid, {"text": text, "length": len(text)}, None) for uid, text in enumerate(data)])
    
    # Filter by score
    print(embeddings.search("select text, score from txtai where similar('hiking danger') and score >= 0.15"))
    
    # Filter by metadata field 'length'
    print(embeddings.search("select text, length, score from txtai where similar('feel good story') and score >= 0.05 and length >= 40"))
    
    # Run aggregate queries
    print(embeddings.search("select count(*), min(length), max(length), sum(length) from txtai"))
    
    [{'text': 'The National Park Service warns against sacrificing slower friends in a bear attack', 'score': 0.3151372969150543}]
    [{'text': 'Maine man wins $1M from $25 lottery ticket', 'length': 42, 'score': 0.08329011499881744}]
    [{'count(*)': 6, 'min(length)': 39, 'max(length)': 94, 'sum(length)': 387}]
    
    上の例では、テキストの長さを簡単に追加します.Txtai 4.0から始まると、インデックスメソッドはデータフィールドに辞書を受け取ります.
    番目のクエリは、類似のクエリ句と共にメタデータフィールド長にフィルター処理されます.これは、最高の結果を識別するために伝統的なフィルタリングで類似性検索の大きな混合を与えます.

    オブジェクトストレージ


    メタデータに加えて、バイナリコンテンツもドキュメントと関連付けることができます.次の例では、イメージをダウンロードし、関連付けられたテキストと共にそれを埋め込みインデックスにアップロードします.
    import urllib
    
    from IPython.display import Image
    
    # Get an image
    request = urllib.request.urlopen("https://raw.githubusercontent.com/neuml/txtai/master/demo.gif")
    
    # Upsert new record having both text and an object
    embeddings.upsert([("txtai", {"text": "txtai executes machine-learning workflows to transform data and build AI-powered semantic search applications.", "object": request.read()}, None)])
    
    # Query txtai for the most similar result to "machine learning" and get associated object
    result = embeddings.search("select object from txtai where similar('machine learning') limit 1")[0]["object"]
    
    # Display image
    Image(result.getvalue(), width=600)
    

    ラッピング


    この記事はTxtaiの簡単な概観を与えた.これはちょうどTxtaiが行うことができます表面を傷です.次のリンクには、埋め込み型、パイプライン、ワークフロー、およびAPIを使用して、セマンティック検索アプリケーションを構築する方法の例があります.
  • Documentation for txtai
  • Full list of examples