つまり、とても高速でチャンクしたいということですね。

2026/01/06 2:19

つまり、とても高速でチャンクしたいということですね。

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

概要:
Memchunk は Retrieval‑Augmented Generation (RAG) パイプライン向けに設計された高性能なチャンク化ライブラリです。デリミタの数に応じて最適な検索戦略を自動で選択します。1〜3 個のデリミタの場合は SIMD 検索(

memchr
memrchr
,
memrchr2
,
memrchr3
を使用)、4 以上の場合は事前に構築された 256 エントリーのルックアップテーブル、そしてチャンク境界直前の最後のデリミタを見つけるために逆方向検索(
memrchr
)を行います。この設計により、句点・改行・疑問符など意味的境界で分割しながら、文の断片化を回避し、メモリ確保を最小限に抑えます。
20 GB の英語 Wikipedia ダンプでベンチマークすると、約 164 GB/s(~120 ms)のスループットを実現し、Rust ライブラリの kiru (4.5 GB/s) や Python ツールの langchain (0.35 GB/s) を大幅に上回ります。Memchunk はオフセットを返すため、呼び出し側はコピーせずにスライスできます。Python では
memoryview
、JavaScript/Node では
subarray
を通じてゼロコピービューが提供されます。バインディングは crates.io、PyPI、npm で入手可能です。
元々、Wikipedia スケールのデータに対する以前の Chonkie ライブラリの性能限界から着想を得た Memchunk は、LMM 取得パイプラインで大規模テキストコーパスのスループット最大化のために、デリミタ数に応じて SIMD とルックアップのどちらを選択するかという核心的な革新を持っています。

本文

Chonkie → Memchunk:検索用テキストを分割する最速手段

私たちは RAG パイプライン向けのチャンクライブラリ「chonkie」を開発してきましたが、ある時点で Wikipedia ほどの規模のデータセットでベンチマークを始めました。すると、動作が…遅く感じられました。耐え難いほどではありませんが、十分に遅いため「ここで理論上限はどこまで?」と疑問になりました。抽象化をすべて捨て、メタルレベルでやるとテキスト分割はどれだけ高速化できるでしょうか?

この記事ではその探索過程と、最終的に「memchunk」を作り上げた経緯について書きます。


1. チャンクとは何なのか?

LLM と検索を組み合わせて何かを構築する際は、巨大なテキストを埋め込みモデルやコンテキストウィンドウに収まる小さな単位へ分割しないといけません。
最もシンプルなのは「N 文字ごとに区切る」ことですが、これだと文を途中で切ってしまい検索品質が低下します。

賢い方法:意味的境界(句点・改行・疑問符など)で分割する。
例:

"Hello world. How are you?"
→ ["Hello world.", " How are you?"]

2. 区切り文字だけで十分なのはなぜ?

  • トークンベース文字数ベースのチャンクは文末を意識せずに N トークン/N バイトごとに分割します。
    例:

    "The quick brown fox jumps over the la"
    "zy dog."
    のように不完全な文が出来上がります。

  • 区切り文字ベースでは

    .
    ?
    \n
    で切るだけで自然な境界を保てます。NLP パイプラインや埋め込みモデルを使わず、単純にバイト検索で済むため高速化が可能です。


3. memchr の登場

Andrew Gallant が開発した memchr クレートは、複数の最適化層を持つバイト検索ライブラリです。

3‑1. フォールバック:SWAR(SIMD Within A Register)

SIMD 命令が無くても memchr は高速です。汎用実装では SWAR を使用し、64 ビット演算で 8 バイトずつ処理します。

fn has_zero_byte(x: usize) -> bool {
    const LO: usize = 0x0101010101010101;
    const HI: usize = 0x8080808080808080;
    (x.wrapping_sub(LO) & !x & HI) != 0
}

has_zero_byte
は、ゼロバイトに対して
-1
を引くことでキャリーが高ビットへ伝播し、分岐や個別のループを不要にします。

3‑2. 高速経路:AVX2/SSE2

x86_64 で SIMD が利用可能なら、memchr はベクトル命令へ切り替わります。AVX2 では 32 バイトを一度に処理できます。

let needle_vec = _mm256_set1_epi8(needle as i8);
let chunk      = _mm256_loadu_si256(haystack);
let matches    = _mm256_cmpeq_epi8(chunk, needle_vec);
let mask       = _mm256_movemask_epi8(matches);
if mask != 0 {
    // 少なくとも一文字が一致。trailing_zeros() が位置を返す。
}

SSE2(16 バイト)と AVX2(32 バイト)のハイブリッド戦略も採用し、ハヤスタックのサイズに応じて最適なパスを選びます。

3‑3. API

バリアント説明
memchr(needle, haystack)
単一バイト検索
memchr2(n1, n2, haystack)
2 つのバイトのどちらかを検索
memchr3(n1, n2, n3, haystack)
3 つのバイトのいずれかを検索

4 バイト以上はサポートしていません。理由は、追加の比較と OR 演算が増えるためオーバーヘッドが大きくなるからです。


4. 区切り文字が 3 より多い場合

'\n'
,
'.'
,
'?'
,
'!'
,
';'
といった 5 つの区切り文字を扱うと memchr は直接対応できません。そこで 256 エントリのルックアップテーブル を使います。

fn build_table(delimiters: &[u8]) -> [bool; 256] {
    let mut table = [false; 256];
    for &byte in delimiters { table[byte as usize] = true; }
    table
}

fn is_delimiter(byte: u8, table: &[bool; 256]) -> bool {
    table[byte as usize]
}

配列アクセスだけで O(1) の処理が可能です。SIMD より速くはありませんが、任意の区切り文字セットを扱え、巨大入力でも数百 GB/s のスループットを維持します。


5. 後ろから検索する理由

フロント側で検索すると、最初に見つかった区切り文字までしか止められません。最適な分割点はさらに近い場所にあるかもしれないため、多くのマッチとインデックス更新が必要になります。

逆に memrchr(memchr の逆)で

chunk_size
から後ろへ検索すれば、最初にヒットした区切り文字が分割点となります。操作数を大幅に減らせるため、全体のオーバーヘッドが低くなります。


6. 実装

memchunk は自動で適切な戦略を選択します。

fn find_last_delimiter(
    window: &[u8],
    delimiters: &[u8],
    table: Option<&[bool; 256]>,
) -> Option<usize> {
    if let Some(t) = table {
        // 区切り文字が 4 個以上:ルックアップテーブルを使用
        window.iter().rposition(|&b| t[b as usize])
    } else {
        match delimiters.len() {
            1 => memchr::memrchr(delimiters[0], window),
            2 => memchr::memrchr2(delimiters[0], delimiters[1], window),
            3 => memchr::memrchr3(
                delimiters[0],
                delimiters[1],
                delimiters[2],
                window,
            ),
            _ => None,
        }
    }
}

テーブルは最初のイテレーションで遅延構築され、以降は高速に動作します。


7. ベンチマーク

他の Rust チャンクライブラリと比較しました(サイズ・区切り文字数が異なるケースも含む)。

ライブラリスループット
memchunk164 GB/s
kiru4.5 GB/s (36×遅い)
langchain0.35 GB/s (469×遅い)
semchunk0.013 GB/s (12,615×遅い)
llama‑index0.0035 GB/s (46,857×遅い)
text‑splitter0.0017 GB/s (96,471×遅い)

ファイルサイズと区切り文字数によって多少変動しますが、最悪でも数百 GB/s の範囲に収まります。実際に英語 Wikipedia(約20 GB)を分割するのは 約120 ms で完了しました。


8. Python と WASM バインディング

chonkie は Python ライブラリなので、Python 用バインディングも必要でした。さらにブラウザや Node.js 向けに WASM を追加しています。

from memchunk import chunk

text = "Hello world. How are you?"
for slice in chunk(text, size=4096, delimiters=".?"):
    print(bytes(slice))
import { chunk } from "memchunk";

const text = new TextEncoder().encode("Hello world. How are you?");
for (const slice of chunk(text, { size: 4096, delimiters: ".?" })) {
  console.log(new TextDecoder().decode(slice));
}

両方とも ゼロコピー のビュー(Python では

memoryview
、JavaScript では
subarray
)を返すため、FFI 境界でもほぼ同等のパフォーマンスが得られます。


9. まとめ

ここで紹介したテクニックは新しいものではありません。SIMD 検索やルックアップテーブルは教科書的手法です。しかし、いつどちらを使うかを知ることにこそ勝負があります。

  1. 区切り文字 1〜3 個 → memchr の SIMD 検索
  2. 区切り文字 4 個以上 → 256 エントリのテーブル
  3. 割当はできるだけ最小化し、オフセットを返す

memchunk は crates.io、PyPI、npm に公開されています。ぜひ試してみてください!

同じ日のほかのニュース

一覧に戻る →

2026/01/06 6:05

ベネズエラで停電が起きた際に、BGP に異常が発生しました。

## Japanese Translation: --- ## Summary ロウオービットセキュリティのニュースレターは、ベネズエラが1月2日に停電した際に発生した疑わしいBGP異常を報告しています(Cloudflare Radar のタイムスタンプ 15:40 UTC)。Cloudflare Radar は CANTV (AS 8048) が自身の ASN を **10 回** 前置していることと、BGP 公開が急増し、その後広告される IP 空間が減少した異常なスパイクを示しています。200.74.224.0/20 ブロックから 8 つのプレフィックスが `…52320 8048 …` の経路で Sparkle(イタリア)と GlobeNet(コロンビア)を通じてリークされました。公開 BGP フィード(ris.ripe.net、bgpdump)は異常な AS‑path 構造を確認しており、Sparkle は RPKI フィルタリングが欠如しているため isbgpsafeyet.com で「unsafe」とリストされており、通常のトラフィックにとってルートが魅力的ではありません。 WHOIS データはリークされたプレフィックスがカラカスの Dayco Telecom に属していることを示しています。逆 DNS ルックアップは、これらの範囲が銀行、ISP、およびメールサーバーなどの重要インフラストラクチャをホストしていることを明らかにします。BGP アクティビティのタイミングは政治的不安と一致し(1月3日に爆発報告およびマドゥロが USS Iwo Jima に登場)、国家レベルでの悪用または意図的なルーティング操作を示唆しています。 ニュースレターは、通信事業者、ホスティングプロバイダー、およびセキュリティ企業に対し、ユーザーと重要インフラストラクチャをトラフィックの傍受や劣化から保護するために BGP 検証(例:RPKI)を強化するよう促しています。

2026/01/06 7:10

なぜAIは2025年に就業市場に参加しなかったのでしょう?

## Japanese Translation: この記事は、2025年までにAIエージェント革命が起こるという高い期待が過大であると主張しています。サム・オルトマン、ケビン・ワイル、マーク・ベニオフはすべて急速な採用と「デジタル労働」のブームを予測しましたが、実際のテスト(例:ChatGPTエージェントがドロップダウンメニューをナビゲートするのに14分かかったケース)では、大規模言語モデルは未だ鈍く不安定であることが示されています。ガリ・マーカスやアンドレイ・カルパチといったシリコンバレーの懐疑派もこれらの限界を認めており、カルパチはこの時期を「エージェントの十年」と呼びました。著者は、まだ信頼できるデジタル従業員を構築する方法がわからないことを指摘し、未来の仮想的な利益よりも現在の控えめな能力に焦点を移すべきだと訴えています。2026年には、実際の取り組みとして段階的な統合を推奨し、企業はまず小規模プロジェクトで試験運用するよう促し、政策立案者には仮説ではなく現在直面しているAIリスクに対処するよう呼びかけています。 ## Text to translate (incorporating missing details and avoiding inference):** The article argues that high‑profile predictions of an AI‑agent revolution by 2025 have been overblown. Sam Altman, Kevin Weil, and Mark Benioff all forecasted rapid adoption and a “digital labor” boom, but real‑world tests—such as ChatGPT Agent spending fourteen minutes navigating a drop‑down menu—show that large language models remain clumsy and unreliable. Silicon Valley skeptics like Gary Marcus and Andrej Karpathy acknowledge these limitations; Karpathy even referred to the period as the “Decade of the Agent.” The author notes that we still do not know how to build reliable digital employees, and urges a shift in focus from speculative future gains to the current modest capabilities. In 2026, the piece calls for realistic engagement: incremental integration rather than wholesale automation, encouraging companies to pilot small‑scale projects first and prompting policymakers to address present AI risks instead of hypothetical ones.

2026/01/06 1:47

**Show HN:** *Tailsnitch – Tailscale 用のセキュリティ監査ツール*

## Japanese Translation: **Tailsnitch** は、52項目を7つのカテゴリ(アクセス、認証、ネットワーク、SSH、ログ、デバイス、DNS)に分類した検査で、誤設定や過度に許容的なアクセス制御、ベストプラクティス違反を監査する軽量CLIツールです。 ユーザーは `tailsnitch` のようなシンプルなコマンドで実行し、結果を severity(`--severity`)、カテゴリ(`--category`)、特定のチェックID(`--checks`)または tailnet(`--tailnet`)でフィルタリングでき、SOC 2 証拠として JSON または CSV へエクスポートできます。 ツールは `tailsnitch --fix` による対話型修復をサポートし、dry‑run、auto‑select、および古いデバイス、保留中の承認、auth keys、タグなどの問題を自動的に修正するオプションがあります。 認証は OAuth(推奨)または API キーで行われます;監査モードでは `policy_file:read` と `devices:core:read` のスコープが必要で、修復モードではさらに `auth_keys` と `devices:core` が必要です。 インストールは簡単です:GitHub Releases から事前ビルドされたバイナリをダウンロードするか、`go install github.com/Adversis/tailsnitch@latest` を実行するか、ソースコード(`git clone https://github.com/Adversis/tailsnitch.git`)をビルドします。 既知のリスクは `.tailsnitch-ignore` ファイルで抑制できます(例:`ACL‑008` や `DEV‑006` のようなエントリー)。このファイルは現在とホームディレクトリに検索され、`--no-ignore` で無効化可能です。 Tailnet‑Lock チェック(`DEV‑010`、`DEV‑012`)にはローカルの Tailscale CLI が必要で、遠隔監査時にはマシンの状態を反映し、`--tailscale-path` を使用して上書きできます。 JSON エクスポートはポストプロセッシング(例:`jq` で失敗や severity の概要を一覧表示)用に設計されており、`--soc2 json` または `--soc2 csv` により SOC 2 証拠の生成もサポートします。 最後に、Tailsnitch は CI/CD パイプライン(GitHub Actions など)へ統合でき、重大または高 severity の発見があった場合にビルドを自動的に失敗させることで、チームが継続的にセキュリティポリシーを強制するのに役立ちます。

つまり、とても高速でチャンクしたいということですね。 | そっか~ニュース