@octomil/browser 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -34702,17 +34702,14 @@ async function runLocalGeneration(request, config) {
34702
34702
  return extractGeneratedText(generation);
34703
34703
  }
34704
34704
  async function getGenerator(config) {
34705
- const key = JSON.stringify([
34706
- config.runtimeModel,
34707
- resolveDevice(config.device),
34708
- config.dtype
34709
- ]);
34705
+ const device = await resolveDevice(config.device);
34706
+ const key = JSON.stringify([config.runtimeModel, device, config.dtype]);
34710
34707
  let pending = pipelineCache.get(key);
34711
34708
  if (!pending) {
34712
34709
  pending = (async () => {
34713
34710
  const { pipeline: pipeline3 } = await importTransformers(config);
34714
34711
  return pipeline3("text-generation", config.runtimeModel, {
34715
- device: resolveDevice(config.device),
34712
+ device,
34716
34713
  dtype: config.dtype
34717
34714
  });
34718
34715
  })();
@@ -34732,11 +34729,65 @@ async function importTransformers(config) {
34732
34729
  }
34733
34730
  return transformers;
34734
34731
  }
34735
- function resolveDevice(device) {
34736
- if (device === "webgpu" || device === "wasm") {
34737
- return device;
34732
+ var resolvedDeviceCache = null;
34733
+ async function resolveDevice(device) {
34734
+ if (device === "webgpu" || device === "wasm") return device;
34735
+ if (resolvedDeviceCache) return resolvedDeviceCache;
34736
+ const result = await probeWebGPU();
34737
+ resolvedDeviceCache = result;
34738
+ return result;
34739
+ }
34740
+ async function probeWebGPU() {
34741
+ try {
34742
+ if (typeof navigator === "undefined" || !("gpu" in navigator)) return "wasm";
34743
+ const gpu = navigator.gpu;
34744
+ const adapter = await gpu.requestAdapter();
34745
+ if (!adapter) return "wasm";
34746
+ const device = await adapter.requestDevice();
34747
+ const module2 = device.createShaderModule({
34748
+ code: `@group(0) @binding(0) var<storage, read_write> out: array<f32>;
34749
+ @compute @workgroup_size(1)
34750
+ fn main() { out[0] = 42.0; }`
34751
+ });
34752
+ const storageBuffer = device.createBuffer({
34753
+ size: 4,
34754
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
34755
+ });
34756
+ const readBuffer = device.createBuffer({
34757
+ size: 4,
34758
+ usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST
34759
+ });
34760
+ const bindGroupLayout = device.createBindGroupLayout({
34761
+ entries: [{ binding: 0, visibility: GPUShaderStage.COMPUTE, buffer: { type: "storage" } }]
34762
+ });
34763
+ const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [bindGroupLayout] });
34764
+ const pipeline3 = device.createComputePipeline({
34765
+ layout: pipelineLayout,
34766
+ compute: { module: module2, entryPoint: "main" }
34767
+ });
34768
+ const bindGroup = device.createBindGroup({
34769
+ layout: bindGroupLayout,
34770
+ entries: [{ binding: 0, resource: { buffer: storageBuffer } }]
34771
+ });
34772
+ const encoder = device.createCommandEncoder();
34773
+ const pass = encoder.beginComputePass();
34774
+ pass.setPipeline(pipeline3);
34775
+ pass.setBindGroup(0, bindGroup);
34776
+ pass.dispatchWorkgroups(1);
34777
+ pass.end();
34778
+ encoder.copyBufferToBuffer(storageBuffer, 0, readBuffer, 0, 4);
34779
+ device.queue.submit([encoder.finish()]);
34780
+ await readBuffer.mapAsync(GPUMapMode.READ);
34781
+ const data = new Float32Array(readBuffer.getMappedRange());
34782
+ const value = data[0];
34783
+ readBuffer.unmap();
34784
+ storageBuffer.destroy();
34785
+ readBuffer.destroy();
34786
+ device.destroy();
34787
+ return value === 42 ? "webgpu" : "wasm";
34788
+ } catch {
34789
+ return "wasm";
34738
34790
  }
34739
- return typeof navigator !== "undefined" && "gpu" in navigator ? "webgpu" : "wasm";
34740
34791
  }
34741
34792
  function renderGenerationInput(generator, messages) {
34742
34793
  const applyChatTemplate = generator.tokenizer?.apply_chat_template;