From c968726891324bba5dd315d2f64a90ac99fc64fc Mon Sep 17 00:00:00 2001 From: Ronald Tse Date: Wed, 21 Oct 2026 12:34:28 +0800 Subject: [PATCH 1/2] =?UTF-8?q?ci(WO71):=20conformance=20matrix=20?= =?UTF-8?q?=E2=80=94=20every=20shipped=20model=20byte-exact=20in=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A conformance-matrix job downloads the frozen vectors + model zips from the models Releases (index sha256 verified first) and replays each fixture byte-exactly through the runtime. urd-g2p (split parts) joins via the resolver in a later pass. --- .github/workflows/rake.yml | 36 +++++++++++++++++++++++++ spec/interscript/ml/conformance_spec.rb | 28 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 spec/interscript/ml/conformance_spec.rb diff --git a/.github/workflows/rake.yml b/.github/workflows/rake.yml index db29f65e..1bb433b0 100644 --- a/.github/workflows/rake.yml +++ b/.github/workflows/rake.yml @@ -101,3 +101,39 @@ jobs: ruby-version: "3.4" bundler-cache: true - run: bundle exec standardrb + + conformance-matrix: + name: Conformance matrix (frozen fixtures) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: "3.3" + bundler-cache: true + - name: Download fixtures (GitHub Releases channel) + run: | + mkdir -p fixtures && cd fixtures + BASE="https://github.com/interscript/interscript-models/releases/download" + curl -fsSL -o models-index.yaml "$BASE/index-v12/models-index.yaml" + curl -fsSL -o models-index.yaml.sha256 "$BASE/index-v12/models-index.yaml.sha256" + shasum -a 256 -c models-index.yaml.sha256 + for v in urd-diac-base fas-diac-base urd-g2p-base; do + curl -fsSL -O "$BASE/index-v12/$v-vectors.json" + done + # the two single-zip models; urd-g2p (split parts) resolves + # via the runtime resolver in a later matrix pass + for m in urd-diac-base-1.0 fas-diac-base-1.0; do + url=$(ruby -ryaml -e "puts YAML.load_file('models-index.yaml')['models']['$m']['url']") + curl -fsSL -o "$m.zip" "$url" + done + - name: Run the matrix + run: | + for pair in "urd-diac-base-1.0 urd-diac-base" "fas-diac-base-1.0 fas-diac-base"; do + set -- $pair + echo "::group::$1" + SECRYST_E2E_ZIP="$PWD/fixtures/$1.zip" \ + CONFORMANCE_VECTORS="$PWD/fixtures/$2-vectors.json" \ + bundle exec rspec spec/interscript/ml/conformance_spec.rb + echo "::endgroup::" + done diff --git a/spec/interscript/ml/conformance_spec.rb b/spec/interscript/ml/conformance_spec.rb new file mode 100644 index 00000000..ff144fbe --- /dev/null +++ b/spec/interscript/ml/conformance_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require "json" +require "interscript/ml" + +# The frozen-fixture contract (interscript-models/conformance/) — the +# ruby runtime must reproduce a model's vectors byte-exactly under the +# declared decode mode, or the change does not merge. +RSpec.describe "frozen conformance fixtures" do + before do + skip "set CONFORMANCE_VECTORS and SECRYST_E2E_ZIP" unless + ENV["CONFORMANCE_VECTORS"] && ENV["SECRYST_E2E_ZIP"] + end + + it "reproduces the vectors byte-exactly (single-row-greedy)" do + vectors = JSON.parse(File.read(ENV["CONFORMANCE_VECTORS"])) + expect(vectors["decode"]["mode"]).to eq("single-row-greedy") + model = Interscript::ML::Translator.new(model_file: ENV["SECRYST_E2E_ZIP"]) + failures = [] + vectors["vectors"].each do |v| + got = model.translate(v["src"]) + failures << "#{v["src"].inspect} -> #{got.inspect} (expected #{v["out"].inspect})" if got != v["out"] + end + expect(failures).to be_empty, + "#{vectors['model']}: #{failures.length}/#{vectors['vectors'].length} mismatched\n" + + failures.first(3).join("\n") + end +end From cd67de287253b448235f1262f386554c63c8aeb8 Mon Sep 17 00:00:00 2001 From: Ronald Tse Date: Wed, 21 Oct 2026 14:01:08 +0800 Subject: [PATCH 2/2] fix(WO79): single-thread decode sessions (byte-exact contract across environments) --- lib/interscript/ml/byt5_onnx.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/interscript/ml/byt5_onnx.rb b/lib/interscript/ml/byt5_onnx.rb index 6c2df340..375926c3 100644 --- a/lib/interscript/ml/byt5_onnx.rb +++ b/lib/interscript/ml/byt5_onnx.rb @@ -38,7 +38,9 @@ def id def build_session(graphs, name) path = File.join(@tmpdir, name) File.binwrite(path, graphs.fetch(name)) - OnnxRuntime::Model.new(path) + # single-thread decode: the conformance contract is byte-exact + # across environments (WO79); multi-thread fp16 ties flip rows + OnnxRuntime::Model.new(path, intra_op_num_threads: 1) end def zero_pasts