Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tfjs-models: make pose-detection deno compatible #6746

Closed
andykais opened this issue Aug 11, 2022 · 32 comments
Closed

tfjs-models: make pose-detection deno compatible #6746

andykais opened this issue Aug 11, 2022 · 32 comments
Labels
stalled stat:awaiting response type:feature New feature or request type:support user support questions

Comments

@andykais
Copy link

andykais commented Aug 11, 2022

I am attempting to get tensorflowjs running within deno. A basic script like the following will work:

import * as tf from 'https://cdn.skypack.dev/@tensorflow/tfjs'
import 'https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu'

// initialize tensorflow
await tf.setBackend('webgpu')
await tf.ready()
const tensor = tf.tensor1d([0])
tensor.print()
deno run --allow-write --allow-read --unstable mod.ts

I can also load up a model, specifically over http, using the file:// protocol actually still triggers a fetch, which deno fails on.

import * as tf from 'https://cdn.skypack.dev/@tensorflow/tfjs'
import 'https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu'

// initialize tensorflow
await tf.setBackend('webgpu')
await tf.ready()

const model = await tf.loadGraphModel(`https://storage.googleapis.com/tfhub-tfjs-modules/google/tfjs-model/movenet/singlepose/lightning/4/model.json`, {
  fetchFunc: fetch
})

However, I would like to be able to reuse some of the code in tfjs-models, since there is a decent amount of code that makes the output from the models useful. This is the following code snippet I want to get working:

import * as tf from 'https://cdn.skypack.dev/@tensorflow/tfjs'
import 'https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu'
import * as poseDetection from 'https://cdn.skypack.dev/@tensorflow-models/pose-detection';

// initialize tensorflow
await tf.setBackend('webgpu')
await tf.ready()

const detectorConfig = {
  modelType: poseDetection.movenet.modelType.SINGLEPOSE_LIGHTNING,
}
const detector = await poseDetection.createDetector(poseDetection.SupportedModels.MoveNet, detectorConfig)

System information MacOS M1

  • TensorFlow.js version (you are using): v3.14.0
  • Are you willing to contribute it (Yes/No): Yes

Describe the feature and the current behavior/state.
tfjs throws an error

error: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'fetch')
      this.fetch = env().platform.fetch;

Will this change the current api? How?
yes, adding a third option to the createDetector method. Example:

const detector = await poseDetection.createDetector(
  poseDetection.SupportedModels.MoveNet,
  detectorConfig,
  { fetchFunc: fetch }
)

Who will benefit with this feature?
anyone porting tensoflowjs to deno trying to use the pose detection

Any Other info.
deno --version

deno 1.24.1 (release, aarch64-apple-darwin)
v8 10.4.132.20
typescript 4.7.4
@andykais andykais added the type:feature New feature or request label Aug 11, 2022
@google-ml-butler google-ml-butler bot added the type:support user support questions label Aug 11, 2022
@pyu10055
Copy link
Collaborator

pyu10055 commented Aug 11, 2022

@andykais Thank you for trying tfjs in deno.
One thing would be good to be confirmed first, what is the result for

console.log(tf.env().getBool('IS_NODE'));
console.log(tf.env().getBool('IS_BROWSER'));

If they are both false, then you need a new platform file to expose the platform specific APIs (i.e. fetch)

If you are interested in contributing, it would be great to add the flag and platform file to TFJS repo in order to support deno better.

@andykais
Copy link
Author

that prints

false
false

I may be able to get away with the browser platform if I can somehow force that. Deno implements most browser apis. Is it possible to manually force the platform? If not, can you at least point me to where it is detected?

@andykais
Copy link
Author

yeah so looking at the browser_platform.ts file, this should function fine in deno, if we can force it https://github.com/tensorflow/tfjs/blob/master/tfjs-core/src/platforms/platform_browser.ts. IndexedDB is not implemented in deno, but that appears to be an optional requirement for the browser platform. Still havent found where we detect the platform. I imagine the indexedDB is used to cache the models?

@andykais
Copy link
Author

Ok I see. Here it is

export function isBrowser(): boolean {
. It is because of window.document != null. In deno, window.document is undefined.

So actually, I think this could be possibly be solved by simply removing the window.document check entirely. A quick scan of the tfjs repo shows that the only reference to window.document is in this isBrowser() function so it feels like it might be unnecessary (tfjs isnt interacting with the document tree in any way).

@andykais andykais changed the title tfjs-models: pose-detection propogate fetchFunc option tfjs-models: make pose-detection deno compatible Aug 12, 2022
@pyu10055
Copy link
Collaborator

I think it is possible to make deno looks like browser, but conceptually it is not a browser.
It might have more efficient way of doing things relative to browser.

If you want to hack the API to testing it out, it might be easier to inject a mock document object to window variable.

@andykais
Copy link
Author

andykais commented Aug 15, 2022

I guess what I am describing is "duck typing", which to a degree, is what you already are checking. You have a check that is essentially: if it looks like a browser, treat it like a browser. All I am suggesting is to not check browser apis that your library does not use.

Alright testing it out, it doesnt actually appear to set IS_BROWSER to true.

;(window as any).document = {} // polyfill for browser detection
import * as tf from 'https://cdn.skypack.dev/@tensorflow/tfjs'
import 'https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu'
import * as poseDetection from 'https://cdn.skypack.dev/@tensorflow-models/pose-detection';


// initialize tensorflow
await tf.setBackend('webgpu')
await tf.ready()

console.log('isBrowser:', tf.device_util.isBrowser())
console.log('IS_BROWSER:', tf.env().getBool('IS_BROWSER'));

this logs

isBrowser: true
IS_BROWSER: false

either window has a different scope inside these modules, or I am reading the code wrong. I can eventually get the tfjs-models repo to build in deno, but its going to require building a import_map.json for module resolution, or bundling for the browser. Doable, but its just going to take time to debug

Actually, this doesnt seem to work either.

;(window as any).document = {} // polyfill for browser detection
import * as tf from 'https://cdn.skypack.dev/@tensorflow/tfjs'
tf.env().set('IS_BROWSER', true)
import 'https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu'
import * as poseDetection from 'https://cdn.skypack.dev/@tensorflow-models/pose-detection';


// initialize tensorflow
await tf.setBackend('webgpu')
await tf.ready()

console.log('isBrowser:', tf.device_util.isBrowser())
console.log('IS_BROWSER:', tf.env().getBool('IS_BROWSER'));

const detectorConfig = {
  modelType: poseDetection.movenet.modelType.SINGLEPOSE_LIGHTNING,
}
const detector = await poseDetection.createDetector(poseDetection.SupportedModels.MoveNet, detectorConfig)

it still fails with

isBrowser: true
IS_BROWSER: true
error: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'fetch')
      this.fetch = env().platform.fetch;

I suppose theres more debugging to do

@haoyunfeix
Copy link
Contributor

The reason might be the env IS_BROWSER set to TURE after register platforms, miss the timing of creating browser platforms.
One hack way to manually set browser platform as following code may solve this simple, since deno has supported LocalStorage IOHandler.

;(window as any).document = {} // polyfill for browser detection
import * as tf from 'https://cdn.skypack.dev/@tensorflow/tfjs'
tf.env().set('IS_BROWSER', true)
import {PlatformBrowser} from 'https://cdn.skypack.dev/@tensorflow/tfjs-core/dist/platforms/platform_browser'
tf.env().setPlatform('browser', new PlatformBrowser());
import 'https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu'
import * as poseDetection from 'https://cdn.skypack.dev/@tensorflow-models/pose-detection';


// initialize tensorflow
await tf.setBackend('webgpu')
await tf.ready()

console.log('isBrowser:', tf.device_util.isBrowser())
console.log('IS_BROWSER:', tf.env().getBool('IS_BROWSER'));

const detectorConfig = {
  modelType: poseDetection.movenet.modelType.SINGLEPOSE_LIGHTNING,
}
const detector = await poseDetection.createDetector(poseDetection.SupportedModels.MoveNet, detectorConfig)

@google-ml-butler
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you.

@andykais
Copy link
Author

@haoyunfeix I tried out your example and was able to at least get tensorflowjs to register the platform as deno. Going one step further to estimate a pose however, yields this error:

import * as jpegts from "https://deno.land/x/jpegts@1.1/mod.ts";
;(window as any).document = {} // polyfill for browser detection
import * as tf from 'https://cdn.skypack.dev/@tensorflow/tfjs'
tf.env().set('IS_BROWSER', true)
import {PlatformBrowser} from 'https://cdn.skypack.dev/@tensorflow/tfjs-core/dist/platforms/platform_browser'
tf.env().setPlatform('browser', new PlatformBrowser());
import 'https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu'
import * as poseDetection from 'https://cdn.skypack.dev/@tensorflow-models/pose-detection';


// initialize tensorflow
await tf.setBackend('webgpu')
await tf.ready()

console.log('isBrowser:', tf.device_util.isBrowser())
console.log('IS_BROWSER:', tf.env().getBool('IS_BROWSER'));

const detectorConfig = {
  modelType: poseDetection.movenet.modelType.MULTIPOSE_LIGHTNING,
}
const detector = await poseDetection.createDetector(poseDetection.SupportedModels.MoveNet, detectorConfig)

const file = await Deno.readFile('./sample.jpg')
const image = await jpegts.decode(file)
const poses = await detector.estimatePoses(image);
console.log(poses)
This device doesn't support timestamp-query extension. Start Chrome browser with flag --disable-dawn-features=disallow_unsafe_apis then try again. Or zero will shown for the kernel time when profiling mode isenabled. Using performance.now is not workable for webgpu sinceit doesn't support synchronously to read data from GPU.
isBrowser: true
IS_BROWSER: true
error: Uncaught (in promise) Error: Kernel 'Reciprocal' not registered for backend 'webgpu'
      throw new Error(`Kernel '${kernelName}' not registered for backend '${this.backendName}'`);
            ^
    at Engine.runKernel (https://cdn.skypack.dev/-/@tensorflow/tfjs-core@v3.19.0-amlY93jd2dBqG3L2cxZ0/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-core.js:2535:13)
    at reciprocal_ (https://cdn.skypack.dev/-/@tensorflow/tfjs-core@v3.14.0-1sdjJhmH325m7a84aLb9/dist=es2019,mode=imports/unoptimized/dist/ops/reciprocal.js:24:17)
    at reciprocal__op (https://cdn.skypack.dev/-/@tensorflow/tfjs-core@v3.14.0-1sdjJhmH325m7a84aLb9/dist=es2019,mode=imports/unoptimized/dist/ops/operation.js:34:22)
    at executeOp$1 (https://cdn.skypack.dev/-/@tensorflow/tfjs-converter@v3.14.0-YN7NizmfUVcf8pFaMZEp/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-converter.js:8571:15)
    at https://cdn.skypack.dev/-/@tensorflow/tfjs-converter@v3.14.0-YN7NizmfUVcf8pFaMZEp/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-converter.js:10502:27
    at https://cdn.skypack.dev/-/@tensorflow/tfjs-core@v3.19.0-amlY93jd2dBqG3L2cxZ0/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-core.js:2490:16
    at Engine.scopedRun (https://cdn.skypack.dev/-/@tensorflow/tfjs-core@v3.19.0-amlY93jd2dBqG3L2cxZ0/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-core.js:2500:19)
    at Engine.tidy (https://cdn.skypack.dev/-/@tensorflow/tfjs-core@v3.19.0-amlY93jd2dBqG3L2cxZ0/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-core.js:2489:17)
    at tidy (https://cdn.skypack.dev/-/@tensorflow/tfjs-core@v3.14.0-1sdjJhmH325m7a84aLb9/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-core.js:7781:17)
    at https://cdn.skypack.dev/-/@tensorflow/tfjs-converter@v3.14.0-YN7NizmfUVcf8pFaMZEp/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-converter.js:10502:16

removing the webgpu import and the line await tf.setBackend('webgpu') does output a pose estimation, though its using the cpu backend

@qjia7
Copy link
Contributor

qjia7 commented Aug 31, 2022

error: Uncaught (in promise) Error: Kernel 'Reciprocal' not registered for backend 'webgpu'
throw new Error(Kernel '${kernelName}' not registered for backend '${this.backendName}');

This op was added two weeks ago. Please try the latest webgpu (0.0.1-alpha.13) npm package, or you can build your own from the source. Thanks.

@haoyunfeix
Copy link
Contributor

@andykais, @qjia7 is right, please use latest code, I tried your pasted code with deno cache --reload mod.ts to get webgpu and tfjs updated.
But got error as below:

Initialization of backend webgpu failed
TypeError: device.features.has is not a function
    at new WebGPUBackend (https://cdn.skypack.dev/-/@tensorflow/tfjs-backend-webgpu@v0.0.1-alpha.13-81rwa8j159gasYKEb1qh/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-backend-webgpu.js:1076:45)
    at Object.factory (https://cdn.skypack.dev/-/@tensorflow/tfjs-backend-webgpu@v0.0.1-alpha.13-81rwa8j159gasYKEb1qh/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-backend-webgpu.js:1624:12)
    at async Engine.setBackend (https://cdn.skypack.dev/-/@tensorflow/tfjs-core@v3.20.0-bzrrCCIwo5CExYFUBlDy/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-core.js:2360:34)
    at async file:///workspace/project/tfjswebgpu/tfjs-yunfei/6746/mod2.ts:14:1
WARNING: lavapipe is not a conformant vulkan implementation, testing use only.

I thought it maybe a WebGPU implement bug in deno. Due to WebGPU spec and webidl spec, device.features is a setlike Object and should includes has method, but there is not.

I've submitted a bug to deno upstream denoland/deno#15702

@andykais
Copy link
Author

thanks @haoyunfeix, I did a --reload and see the same error as you now. Curious though that `await tf.setBackend('webgpu') logs an exception, but does not throw it

@haoyunfeix
Copy link
Contributor

It's by design I think, if your throw it means throw exception and abort application, TFJS prefers to tell you hey there is something wrong in setting up webgpu let's keep default cpu backend and make your app running.
tf.setBackend(): Promise<boolean> in another way, you can check API return value in your app design to determine throw exception or not.

Although in our case, the exception happened in import 'https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu', exactly in registerBackend(): boolean, same as above TFJS warns you and returns result computing on default CPU backend.

@vicary
Copy link

vicary commented Sep 14, 2022

I built Deno from source using my fork in PR denoland/deno#15853 and the backend check passes.

I can do await tf.ready(); and tf.getBackend(); gives me "webgpu".

But when I tried to decode the model outputs via await tensor.array();, it throws the following error:

TypeError: Cannot read properties of undefined (reading 'backend')
Full stack trace (click to open)
error: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'backend')
    const srcBackend = info.backend;
                            ^
    at Engine.moveData (https://cdn.skypack.dev/-/@tensorflow/tfjs-core@v3.20.0-bzrrCCIwo5CExYFUBlDy/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-core.js:2463:29)
    at DataStorage.get (https://cdn.skypack.dev/-/@tensorflow/tfjs-core@v3.20.0-bzrrCCIwo5CExYFUBlDy/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-core.js:33:22)
    at WebGPUBackend.convertAndCacheOnCPU (https://cdn.skypack.dev/-/@tensorflow/tfjs-backend-webgpu@v0.0.1-alpha.13-81rwa8j159gasYKEb1qh/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-backend-webgpu.js:1240:39)
    at WebGPUBackend.read (https://cdn.skypack.dev/-/@tensorflow/tfjs-backend-webgpu@v0.0.1-alpha.13-81rwa8j159gasYKEb1qh/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-backend-webgpu.js:1276:10)
    at async Tensor.array (https://cdn.skypack.dev/-/@tensorflow/tfjs-core@v3.20.0-bzrrCCIwo5CExYFUBlDy/dist=es2019,mode=imports/optimized/@tensorflow/tfjs-core.js:1977:18)

I don't mind making more PRs just to push this forward, but I really need help in pinning down the issue in tfjs.

Sidenote

In my Apple M1, the contents of GPUSupportedFeatures looks like this:

[
  "depth-clip-control",
  "depth32float-stencil8",
  "texture-compression-bc",
  "texture-compression-etc2",
  "texture-compression-astc",
  "indirect-first-instance",
  "shader-f16",
  "mappable-primary-buffers",
  "texture-binding-array",
  "storage-resource-binding-array",
  "sampled-texture-and-storage-buffer-array-non-uniform-indexing",
  "uniform-buffer-and-storage-buffer-texture-non-uniform-indexing",
  "address-mode-clamp-to-border",
  "texture-adapter-specific-format-features",
  "vertex-writable-storage",
  "clear-texture"
]

@andykais
Copy link
Author

that seems like its possibly a binding issue, it might be helpful to share a minimal repro code snippet @vicary. This looks like the source line https://github.com/tensorflow/tfjs/blob/master/tfjs-core/src/engine.ts#L424

@vicary
Copy link

vicary commented Sep 15, 2022

@andykais Thanks for the hint. It turns out to be me prematurely disposing a tensor before the promise is resolved, we could definitely use a better error message but that's for another issue.

I can gladly say that my Deno fork basically works for all the use cases I have.

@google-ml-butler
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you.

@google-ml-butler
Copy link

Closing as stale. Please @mention us if this needs more attention.

@google-ml-butler
Copy link

Are you satisfied with the resolution of your issue?
Yes
No

@andykais
Copy link
Author

andykais commented Dec 7, 2022

tensorflow is not working with the current script in the latest version of deno. Running exactly the script described above:

import * as jpegts from "https://deno.land/x/jpegts@1.1/mod.ts";
;(window as any).document = {} // polyfill for browser detection
import * as tf from 'https://cdn.skypack.dev/@tensorflow/tfjs'
tf.env().set('IS_BROWSER', true)
import {PlatformBrowser} from 'https://cdn.skypack.dev/@tensorflow/tfjs-core/dist/platforms/platform_browser'
tf.env().setPlatform('browser', new PlatformBrowser());
import 'https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu'
import * as poseDetection from 'https://cdn.skypack.dev/@tensorflow-models/pose-detection';


// initialize tensorflow
await tf.setBackend('webgpu')
await tf.ready()

console.log('isBrowser:', tf.device_util.isBrowser())
console.log('IS_BROWSER:', tf.env().getBool('IS_BROWSER'));

const detectorConfig = {
  modelType: poseDetection.movenet.modelType.MULTIPOSE_LIGHTNING,
}
const detector = await poseDetection.createDetector(poseDetection.SupportedModels.MoveNet, detectorConfig)

const file = await Deno.readFile('./sample.jpg')
const image = await jpegts.decode(file)
const poses = await detector.estimatePoses(image);
console.log(poses)

runs, but has an empty output of poses ([])

Attempting to update the script to use npm specifiers looks like this:

import * as jpegts from "https://deno.land/x/jpegts@1.1/mod.ts";
;(window as any).document = {} // polyfill for browser detection
import * as tf from 'npm:@tensorflow/tfjs'
tf.env().set('IS_BROWSER', true)
import {PlatformBrowser} from 'npm:@tensorflow/tfjs-core/dist/platforms/platform_browser'
tf.env().setPlatform('browser', new PlatformBrowser());
import 'npm:@tensorflow/tfjs-backend-webgpu'
import * as poseDetection from 'npm:@tensorflow-models/pose-detection';


// initialize tensorflow
await tf.setBackend('webgpu')
await tf.ready()

console.log('isBrowser:', tf.device_util.isBrowser())
console.log('IS_BROWSER:', tf.env().getBool('IS_BROWSER'));

const detectorConfig = {
  modelType: poseDetection.movenet.modelType.MULTIPOSE_LIGHTNING,
}
const detector = await poseDetection.createDetector(poseDetection.SupportedModels.MoveNet, detectorConfig)

const file = await Deno.readFile('./sample.jpg')
const image = await jpegts.decode(file)
const poses = await detector.estimatePoses(image);
console.log(poses)

but this gives the following error:

error: Uncaught SyntaxError: Identifier 'mod' has already been declared
    at <anonymous> (file:///Users/andrew/Library/Caches/deno/npm/registry.npmjs.org/@tensorflow/tfjs/4.1.0/dist/tf.node.js:291:14)

I havent been able to discover the cause of that error, since it appears that the source line specified is not actually where the error is occurring

@google-ml-butler unstale
(if the google butler doesnt unstale this issue then I can just create a new one)

@andykais
Copy link
Author

andykais commented Dec 7, 2022

update, this is a minimally reproducable example that causes the SyntaxError:

import * as jpegts from "https://deno.land/x/jpegts@1.1/mod.ts";
;(window as any).document = {} // polyfill for browser detection
import * as tf from 'npm:@tensorflow/tfjs'
tf.env().set('IS_BROWSER', true)

deno --version output:

deno 1.28.3 (release, aarch64-apple-darwin)
v8 10.9.194.5
typescript 4.8.3

@haoyunfeix
Copy link
Contributor

haoyunfeix commented Dec 9, 2022

@andykais For your first piece of code

runs, but has an empty output of poses ([])

There're 2 known issues in naga program as mentioned in #6842 (comment), it means generated compute shaders were not available for naga when using upstream WebGPU backend(https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu).
So I fixed them in patch master...haoyunfeix:tfjs:fix_6746 for local build, unfortunately this only fixed some basic operations like tf.add(), tf.exp() ... but for the whole model in pose-detection it still got [](see samples in attached file), I'll keep working to figure out if there are some other shaders failed in naga.
6746_upload.zip

@andykais
Copy link
Author

andykais commented Dec 9, 2022

Awesome, glad to hear this is an active issue. @haoyunfeix if you have the ability to reopen this issue could you do that?

@qjia7 qjia7 reopened this Dec 12, 2022
@haoyunfeix
Copy link
Contributor

haoyunfeix commented Dec 17, 2022

As mentioned above, the empty output is caused by invalid shaders for naga.
I fixed all related shaders used by pose-detection in master...haoyunfeix:tfjs:fix_6746, as chrome implementation and naga are mutually exclusive, so this PR will not land in TFJS, we have to wait for gfx-rs/naga#1829 to support const in naga side. Anyway, we finally got a workable pose-detection demo on WebGPU backend in Deno.

I attached the sample code and rebuilt webgpu js file, please try as you like. You can also try with fix_6746 branch to build a local package for yourself.

latest.zip

haoyunfeix added a commit to haoyunfeix/tfjs that referenced this issue Dec 20, 2022
haoyunfeix added a commit to haoyunfeix/tfjs that referenced this issue Dec 20, 2022
haoyunfeix added a commit to haoyunfeix/tfjs that referenced this issue Dec 21, 2022
…s global scope

FIXES BUG: tensorflow#6746
Deno uses Naga for wgsl compilation, but Naga currently uses let for global constants(will be fixed in gfx-rs/naga#1829).
This PR helps WebGPU to run pose-detection models on Deno by removing global constants in shaders.

Address comments
gyagp pushed a commit that referenced this issue Dec 21, 2022
* [webgpu] Use numbers directly instead of `const variables` in shader's global scope

FIXES BUG: #6746
Deno uses Naga for wgsl compilation, but Naga currently uses let for global constants(will be fixed in gfx-rs/naga#1829).
This PR helps WebGPU to run pose-detection models on Deno by removing global constants in shaders.
@haoyunfeix
Copy link
Contributor

@andykais shader problems fixed with #7193, please look forward to the next version(should be https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu@0.0.1-alpha.17, not published yet) can be runnable on your demo.

@google-ml-butler
Copy link

Closing as stale. Please @mention us if this needs more attention.

@google-ml-butler
Copy link

Are you satisfied with the resolution of your issue?
Yes
No

@andykais
Copy link
Author

andykais commented Jan 4, 2023

just sharing back the working code with the most recent fix:

import * as jpegts from "https://deno.land/x/jpegts@1.1/mod.ts";
;(window as any).document = {} // polyfill for browser detection
import * as tf from 'https://cdn.skypack.dev/@tensorflow/tfjs'
import 'https://cdn.skypack.dev/@tensorflow/tfjs-backend-webgpu@0.0.1-alpha.17'
tf.env().set('IS_BROWSER', true)
import {PlatformBrowser} from 'https://cdn.skypack.dev/@tensorflow/tfjs-core/dist/platforms/platform_browser'
tf.env().setPlatform('browser', new PlatformBrowser());
import * as poseDetection from 'npm:@tensorflow-models/pose-detection';

// initialize tensorflow
await tf.setBackend('webgpu')
await tf.ready()

tf.env().set('WEBGPU_DEFERRED_SUBMIT_BATCH_SIZE', 1);
// console.log('isBrowser:', tf.device_util.isBrowser())
// console.log('IS_BROWSER:', tf.env().getBool('IS_BROWSER'));
// console.log(tf.getBackend());

const detectorConfig = {
  modelType: poseDetection.movenet.modelType.MULTIPOSE_LIGHTNING,
}
const detector = await poseDetection.createDetector(poseDetection.SupportedModels.MoveNet, detectorConfig)

const file = await Deno.readFile('./sample.jpg')
const image = await jpegts.decode(file)
const poses = await detector.estimatePoses(image);

console.log(poses)

I am still not able to use npm specifiers for really any of these modules, I assume thats because not all the relevant pieces have been published (though the problematic webgpu backend code has been published on npm https://www.npmjs.com/package/@tensorflow/tfjs-backend-webgpu/v/0.0.1-alpha.17)

@haoyunfeix
Copy link
Contributor

@andykais Thanks for the feedback!

Your pasted code works on my machine, env:
deno 1.28.3 (release, x86_64-pc-windows-msvc), v8 10.9.194.5, typescript 4.8.3,
could you share more about what problems you met?

And did you try to reload your cache? => deno cache --reload mod.ts

Linchenn pushed a commit to Linchenn/tfjs that referenced this issue Jan 9, 2023
…7193)

* [webgpu] Use numbers directly instead of `const variables` in shader's global scope

FIXES BUG: tensorflow#6746
Deno uses Naga for wgsl compilation, but Naga currently uses let for global constants(will be fixed in gfx-rs/naga#1829).
This PR helps WebGPU to run pose-detection models on Deno by removing global constants in shaders.
@haoyunfeix
Copy link
Contributor

Deno latest version 1.30.3 hits an error when loading webgpu backend, refs to denoland/deno#17869

@andykais
Copy link
Author

the script I have above works on deno latest version 1.31.1 (the webgpu backend issue was solved in the deno repo). However, I still cannot use npm specifiers, only skypack imports. A very tiny repro looks like this:

;(window as any).document = {} // polyfill for browser detection
import * as tf from 'npm:@tensorflow/tfjs@4.2.0'
tf.env().set('IS_BROWSER', true)

deno run -A --unstable --check github-issue-repro.ts

error: Uncaught SyntaxError: Identifier 'mod' has already been declared
    at <anonymous> (file:///Users/andrew/Library/Caches/deno/npm/registry.npmjs.org/@tensorflow/tfjs/4.2.0/dist/tf.node.js:233:14)

@mzygmunt
Copy link

mzygmunt commented Nov 8, 2023

the script I have above works on deno latest version 1.31.1 (the webgpu backend issue was solved in the deno repo). However, I still cannot use npm specifiers, only skypack imports. A very tiny repro looks like this:

;(window as any).document = {} // polyfill for browser detection
import * as tf from 'npm:@tensorflow/tfjs@4.2.0'
tf.env().set('IS_BROWSER', true)

deno run -A --unstable --check github-issue-repro.ts

error: Uncaught SyntaxError: Identifier 'mod' has already been declared
    at <anonymous> (file:///Users/andrew/Library/Caches/deno/npm/registry.npmjs.org/@tensorflow/tfjs/4.2.0/dist/tf.node.js:233:14)

I've the same. @andykais Did you find any solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stalled stat:awaiting response type:feature New feature or request type:support user support questions
Projects
None yet
Development

No branches or pull requests

7 participants