| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100 |
- var paddle = paddle || {};
- var flatbuffers = flatbuffers || require('./flatbuffers');
- var protobuf = protobuf || require('./protobuf');
- var python = python || require('./python');
- var base = base || require('./base');
- paddle.ModelFactory = class {
- match(context) {
- const identifier = context.identifier;
- const extension = identifier.split('.').pop().toLowerCase();
- if (identifier === '__model__' || extension === '__model__' || extension === 'paddle' || extension === 'pdmodel') {
- const tags = context.tags('pb');
- if (tags.get(1) === 2) {
- return 'paddle.pb';
- }
- }
- if (extension === 'pbtxt' || extension === 'txt') {
- const tags = context.tags('pbtxt');
- if (tags.has('blocks')) {
- return 'paddle.pbtxt';
- }
- }
- const stream = context.stream;
- if (stream && stream.length > 16 && stream.peek(16).every((value) => value === 0x00)) {
- return 'paddle.params';
- }
- if (paddle.Pickle.open(context)) {
- return 'paddle.pickle';
- }
- if (paddle.Entries.open(context)) {
- return 'paddle.entries';
- }
- if (paddle.NaiveBuffer.open(context)) {
- return 'paddle.naive';
- }
- return undefined;
- }
- open(context, match) {
- return context.metadata('paddle-metadata.json').then((metadata) => {
- switch (match) {
- case 'paddle.naive': {
- return context.require('./paddle-schema').then(() => {
- paddle.schema = flatbuffers.get('paddlelite').paddle.lite.fbs.proto;
- const file = paddle.NaiveBuffer.open(context);
- return new paddle.Model(metadata, file.format, file.model, file.weights);
- });
- }
- default: {
- return context.require('./paddle-proto').then(() => {
- paddle.proto = protobuf.get('paddle').paddle.framework.proto;
- const identifier = context.identifier;
- const parts = identifier.split('.');
- const extension = parts.pop().toLowerCase();
- const base = parts.join('.');
- const openProgram = (stream, match) => {
- const program = {};
- switch (match) {
- case 'paddle.pbtxt': {
- try {
- const reader = protobuf.TextReader.open(stream);
- program.desc = paddle.proto.ProgramDesc.decodeText(reader);
- }
- catch (error) {
- const message = error && error.message ? error.message : error.toString();
- throw new paddle.Error('File text format is not paddle.ProgramDesc (' + message.replace(/\.$/, '') + ').');
- }
- break;
- }
- case 'paddle.pb': {
- try {
- const reader = protobuf.BinaryReader.open(stream);
- program.desc = paddle.proto.ProgramDesc.decode(reader);
- }
- catch (error) {
- const message = error && error.message ? error.message : error.toString();
- throw new paddle.Error('File format is not paddle.ProgramDesc (' + message.replace(/\.$/, '') + ').');
- }
- break;
- }
- default: {
- throw new paddle.Error("Unsupported Paddle format '" + match + "'.");
- }
- }
- const formatVersion = (version) => {
- if (version && version.version && version.version.toNumber) {
- const number = version.version.toNumber();
- if (number > 0) {
- const list = [ Math.floor(number / 1000000) % 1000, Math.floor(number / 1000) % 1000, number % 1000 ];
- if (list.slice(-1).pop() === 0) {
- list.pop();
- if (list.slice(-1).pop() === 0) {
- list.pop();
- }
- }
- return ' v' + list.map((item) => item.toString()).join('.');
- }
- }
- return '';
- };
- program.format = 'PaddlePaddle' + formatVersion(program.desc.version);
- const variables = new Set();
- for (const block of program.desc.blocks) {
- const blockVars = new Set();
- for (const variable of block.vars) {
- if (variable.persistable && variable.type &&
- variable.type.type != paddle.DataType.FETCH_LIST &&
- variable.type.type != paddle.DataType.FEED_MINIBATCH) {
- blockVars.add(variable.name);
- }
- }
- for (const op of block.ops) {
- for (const input of op.inputs) {
- for (const argument of input.arguments) {
- if (blockVars.has(argument)) {
- variables.add(argument);
- }
- }
- }
- }
- }
- program.vars = Array.from(variables).sort();
- return program;
- };
- const createModel = (metadata, format, desc, tensors) => {
- return new paddle.Model(metadata, format, desc, tensors);
- };
- const loadParams = (stream) => {
- const params = [];
- while (stream.position < stream.length) {
- const tensor = paddle.Utility.openTensorDesc(stream);
- params.push(tensor);
- }
- return params;
- };
- const mapParams = (params, program) => {
- const weights = new Map();
- const vars = program.vars.slice();
- for (const param of params) {
- weights.set(vars.shift(), param);
- }
- return weights;
- };
- switch (match) {
- case 'paddle.pickle': {
- const container = paddle.Pickle.open(context);
- return createModel(metadata, container.format, null, container.weights);
- }
- case 'paddle.entries': {
- const container = paddle.Entries.open(context);
- return createModel(metadata, container.format, null, container.weights);
- }
- case 'paddle.params': {
- const file = identifier !== 'params' ? base + '.pdmodel' : 'model';
- const params = loadParams(context.stream);
- return context.request(file, null).then((stream) => {
- const program = openProgram(stream, 'paddle.pb');
- const weights = mapParams(params, program);
- return createModel(metadata, program.format, program.desc, weights);
- }).catch(() => {
- const weights = new Map(params.map((param, index) => [ index.toString(), param ]));
- return createModel(metadata, 'PaddlePaddle Inference Weights', null, weights);
- });
- }
- case 'paddle.pb':
- case 'paddle.pbtxt': {
- const loadEntries = (context, program) => {
- const promises = program.vars.map((name) => context.request(name, null).then((stream) => stream).catch(() => null));
- return Promise.all(promises).then((streams) => {
- const params = streams.map((stream) => stream ? paddle.Utility.openTensorDesc(stream) : null);
- const weights = mapParams(params, program);
- return createModel(metadata, program.format, program.desc, weights);
- });
- };
- const openNumPyArrayPickle = (stream) => {
- const execution = new python.Execution(null);
- const unpickler = python.Unpickler.open(stream, execution);
- const obj = unpickler.load();
- const container = new paddle.Pickle(obj);
- return container.weights || new Map();
- };
- const program = openProgram(context.stream, match);
- if (extension === 'pdmodel') {
- return context.request(base + '.pdiparams', null).then((stream) => {
- const params = loadParams(stream);
- const weights = mapParams(params, program);
- return createModel(metadata, program.format, program.desc, weights);
- }).catch((/* err */) => {
- return context.request(base + '.pdparams', null).then((stream) => {
- const weights = openNumPyArrayPickle(stream);
- return context.request(base + '.pdopt', null).then((stream) => {
- for (const entry of openNumPyArrayPickle(stream)) {
- if (!weights.has(entry[0])) {
- weights.set(entry[0], entry[1]);
- }
- }
- return createModel(metadata, program.format, program.desc, weights);
- }).catch((/* err */) => {
- return createModel(metadata, program.format, program.desc, weights);
- });
- }).catch((/* err */) => {
- return context.request(base + '.pdopt', null).then((stream) => {
- const weights = openNumPyArrayPickle(stream);
- return createModel(metadata, program.format, program.desc, weights);
- }).catch((/* err */) => {
- return loadEntries(context, program);
- });
- });
- });
- }
- if (identifier === 'model') {
- return context.request('params', null).then((stream) => {
- const params = loadParams(stream);
- const weights = mapParams(params, program);
- return createModel(metadata, program.format, program.desc, weights);
- }).catch((/* err */) => {
- return loadEntries(context, program);
- });
- }
- return loadEntries(context, program);
- }
- default: {
- throw new paddle.Error("Unsupported PaddlePaddle format '" + match + "'.");
- }
- }
- });
- }
- }
- });
- }
- };
- paddle.Model = class {
- constructor(metadata, format, programDesc, tensors) {
- this._format = format;
- this._graphs = programDesc ?
- programDesc.blocks.map((block) => new paddle.Graph(metadata, block, tensors)) :
- [ new paddle.Graph(metadata, null, tensors) ];
- }
- get format() {
- return this._format;
- }
- get graphs() {
- return this._graphs;
- }
- };
- paddle.Graph = class {
- constructor(metadata, block, tensors) {
- this._nodes = [];
- this._inputs = [];
- this._outputs = [];
- if (block) {
- this._name = block.idx.toString();
- const args = new Map();
- for (const variable of block.vars) {
- const type = variable.type && variable.type.type && variable.type.lod_tensor && variable.type.lod_tensor.tensor ? paddle.Utility.createTensorType(variable.type.lod_tensor.tensor.data_type, variable.type.lod_tensor.tensor.dims) : null;
- const tensor = variable.persistable && variable.type && variable.type.type != paddle.DataType.FETCH_LIST && variable.type.type != paddle.DataType.FEED_MINIBATCH ? (tensors.get(variable.name) || new paddle.Tensor(type)) : null;
- args.set(variable.name, new paddle.Argument(variable.name, type, tensor));
- }
- const scope = {};
- for (let i = 0; i < block.ops.length; i++) {
- for (const input of block.ops[i].inputs) {
- input.arguments = input.arguments.map((argument) => scope[argument] ? scope[argument] : argument);
- }
- for (const output of block.ops[i].outputs) {
- output.arguments = output.arguments.map((argument) => {
- if (scope[argument]) {
- const next = argument + '\n' + i.toString(); // custom argument id
- scope[argument] = next;
- return next;
- }
- scope[argument] = argument;
- return argument;
- });
- }
- }
- for (const op of block.ops) {
- for (const input of op.inputs) {
- for (const argument of input.arguments) {
- const name = argument;
- if (!args.has(name)) {
- args.set(name, new paddle.Argument(name, null, null));
- }
- }
- }
- for (const output of op.outputs) {
- for (const argument of output.arguments) {
- const name = argument;
- if (!args.has(name)) {
- args.set(name, new paddle.Argument(name, null, null));
- }
- }
- }
- }
- let lastNode = null;
- let lastOutput = null;
- for (const op of block.ops) {
- if (op.type == 'feed') {
- const inputName = op.attrs.filter((attr) => attr.name == 'col')[0].i.toString();
- this._inputs.push(new paddle.Parameter(inputName, op.outputs[0].arguments.map((id) => args.get(id))));
- }
- else if (op.type == 'fetch') {
- const outputName = op.attrs.filter((attr) => attr.name == 'col')[0].i.toString();
- this._outputs.push(new paddle.Parameter(outputName, op.inputs[0].arguments.map((id) => args.get(id))));
- }
- else {
- const node = new paddle.Node(metadata, op, args);
- if (op.inputs.length == 1 && op.inputs[0].arguments.length == 1 &&
- op.outputs.length >= 1 && op.outputs[0].arguments.length == 1 &&
- op.inputs[0].arguments[0].split('\n').shift() == op.outputs[0].arguments[0].split('\n').shift() &&
- lastNode &&
- lastOutput == op.inputs[0].arguments[0].split('\n').shift()) {
- lastNode.chain.push(node);
- }
- else {
- this._nodes.push(node);
- lastNode = null;
- lastOutput = null;
- if (op.outputs.length == 1 && op.outputs[0].arguments.length == 1) {
- lastNode = node;
- lastOutput = op.outputs[0].arguments[0].split('\n').shift();
- }
- }
- }
- }
- }
- else {
- const args = new Map();
- const ops = new Map();
- for (const pair of tensors) {
- const name = pair[0];
- const tensor = pair[1];
- args.set(name, new paddle.Argument(name, tensor.type, tensor));
- const separator = name.indexOf('.') !== -1 ? '.' : '_';
- const regex = /(.*)_((w_attr|scale|weights|offset|b|w|b_attr)_(moment|beta|velocity|mean_square|mean_grad).*)/;
- const parts = separator === '.' ? name.split(separator) : (regex.test(name) ? regex.exec(name).slice(1, 3) : [ '', name ]);
- const parameter_name = parts.pop();
- const op_name = parts.join(separator);
- if (!ops.has(op_name)) {
- ops.set(op_name, { name: op_name, type: 'Weights', inputs: [] });
- }
- const op = ops.get(op_name);
- op.inputs.push({ parameter: parameter_name, arguments: [ name ] });
- }
- for (const pair of ops) {
- const op = pair[1];
- this._nodes.push(new paddle.Node(metadata, op, args));
- }
- }
- }
- get name() {
- return this._name;
- }
- get inputs() {
- return this._inputs;
- }
- get outputs() {
- return this._outputs;
- }
- get nodes() {
- return this._nodes;
- }
- };
- paddle.Parameter = class {
- constructor(name, args) {
- this._name = name;
- this._arguments = args;
- }
- get name() {
- return this._name;
- }
- get visible() {
- return true;
- }
- get arguments() {
- return this._arguments;
- }
- };
- paddle.Argument = class {
- constructor(name, type, initializer) {
- if (typeof name !== 'string') {
- throw new paddle.Error("Invalid argument identifier '" + JSON.stringify(name) + "'.");
- }
- this._name = name;
- this._type = type || null;
- this._initializer = initializer || null;
- }
- get name() {
- return this._name;
- }
- get type() {
- if (this._type) {
- return this._type;
- }
- if (this._initializer) {
- return this._initializer.type;
- }
- return null;
- }
- get initializer() {
- return this._initializer;
- }
- };
- paddle.Node = class {
- constructor(metadata, op, args) {
- const type = op.type;
- this._type = metadata.type(type) || { name: type };
- this._name = op.name || '';
- this._attributes = [];
- this._inputs = [];
- this._outputs = [];
- this._chain = [];
- if (op.attrs) {
- this._attributes = op.attrs.map((attr) => new paddle.Attribute(metadata.attribute(type, this._name), attr));
- }
- if (op.inputs) {
- for (const input of op.inputs) {
- if (input.arguments.length > 0) {
- this._inputs.push(new paddle.Parameter(input.parameter, input.arguments.map((name) => args.get(name))));
- }
- }
- }
- if (op.outputs) {
- for (const output of op.outputs) {
- if (output.arguments.length > 0) {
- this._outputs.push(new paddle.Parameter(output.parameter, output.arguments.map((name) => args.get(name))));
- }
- }
- }
- this._update(this._inputs, 'X');
- this._update(this._inputs, 'Input');
- this._update(this._outputs, 'Y');
- this._update(this._outputs, 'Out');
- }
- get type() {
- return this._type;
- }
- get name() {
- return this._name;
- }
- get attributes() {
- return this._attributes;
- }
- get inputs() {
- return this._inputs;
- }
- get outputs() {
- return this._outputs;
- }
- get chain() {
- return this._chain;
- }
- _update(list, name) {
- let item = null;
- for (let i = 0; i < list.length; i++) {
- if (list[i].name == name) {
- item = list[i];
- list.splice(i, 1);
- break;
- }
- }
- if (item) {
- list.splice(0, 0, item);
- }
- }
- };
- paddle.Attribute = class {
- constructor(schema, attr) {
- this._name = attr.name;
- this._value = '?';
- switch (attr.type) {
- case paddle.AttributeType.STRING:
- this._type = 'string';
- this._value = attr.s;
- break;
- case paddle.AttributeType.STRINGS:
- this._type = 'string[]';
- this._value = Array.from(attr.strings);
- break;
- case paddle.AttributeType.BOOLEAN:
- this._type = 'boolean';
- this._value = attr.b;
- break;
- case paddle.AttributeType.BOOLEANS:
- this._type = 'boolean[]';
- this._value = Array.from(attr.bools);
- break;
- case paddle.AttributeType.FLOAT:
- this._type = 'float32';
- this._value = attr.f;
- break;
- case paddle.AttributeType.FLOATS:
- this._type = 'float[]';
- this._value = Array.from(attr.floats);
- break;
- case paddle.AttributeType.INT:
- this._type = 'int32';
- this._value = attr.i;
- break;
- case paddle.AttributeType.INTS:
- this._type = 'int32[]';
- this._value = Array.from(attr.ints);
- break;
- case paddle.AttributeType.LONG:
- this._type = 'int64';
- break;
- case paddle.AttributeType.LONGS:
- this._type = 'int64[]';
- break;
- default:
- break;
- }
- switch (this._name) {
- case 'use_mkldnn':
- case 'use_cudnn':
- case 'op_callstack':
- case 'op_role':
- case 'op_role_var':
- case 'op_namescope':
- case 'is_test':
- this._visible = false;
- break;
- default:
- break;
- }
- if (schema) {
- if (Object.prototype.hasOwnProperty.call(schema, 'default')) {
- const defaultValue = schema.default;
- const value = this._value;
- if (defaultValue == value) {
- this._visible = false;
- }
- else if (Array.isArray(value) && Array.isArray(defaultValue) && value.length == defaultValue.length) {
- if (value.every((item, index) => item == defaultValue[index])) {
- this._visible = false;
- }
- }
- }
- }
- }
- get name() {
- return this._name;
- }
- get type() {
- return this._type;
- }
- get value() {
- return this._value;
- }
- get visible() {
- return this._visible == false ? false : true;
- }
- };
- paddle.Tensor = class {
- constructor(type, data, kind) {
- this._type = type;
- this._data = data;
- this._kind = kind || '';
- }
- get kind() {
- return this._kind;
- }
- get type() {
- return this._type;
- }
- get state() {
- return this._context().state || null;
- }
- get value() {
- const context = this._context();
- if (context.state) {
- return null;
- }
- context.limit = Number.MAX_SAFE_INTEGER;
- return this._decode(context, 0);
- }
- toString() {
- const context = this._context();
- if (context.state) {
- return '';
- }
- context.limit = 10000;
- const value = this._decode(context, 0);
- return paddle.Tensor._stringify(value, '', ' ');
- }
- _context() {
- const context = {};
- context.index = 0;
- context.count = 0;
- context.state = null;
- if (!this._data) {
- context.state = 'Tensor data is empty.';
- return context;
- }
- if (!this._type) {
- context.state = 'Tensor has no data type.';
- return context;
- }
- context.dataType = this._type.dataType;
- context.shape = this._type.shape.dimensions;
- context.view = new DataView(this._data.buffer, this._data.byteOffset, this._data.byteLength);
- switch (context.dataType) {
- case 'float32':
- case 'int32':
- case 'int64':
- break;
- default:
- context.state = "Tensor data type '" + context.dataType + "' is not implemented.";
- break;
- }
- return context;
- }
- _decode(context, dimension) {
- const shape = context.shape.length !== 0 ? context.shape : [ 1 ];
- const results = [];
- const size = shape[dimension];
- if (dimension == shape.length - 1) {
- for (let i = 0; i < size; i++) {
- if (context.count > context.limit) {
- results.push('...');
- return results;
- }
- switch (context.dataType) {
- case 'float32':
- results.push(context.view.getFloat32(context.index, true));
- context.index += 4;
- context.count++;
- break;
- case 'int32':
- results.push(context.view.getInt32(context.index, true));
- context.index += 4;
- context.count++;
- break;
- case 'int64':
- results.push(context.view.getInt64(context.index, true));
- context.index += 8;
- context.count++;
- break;
- default:
- throw new paddle.Error("Unsupported tensor data type '" + context.dataType + "'.");
- }
- }
- }
- else {
- for (let j = 0; j < size; j++) {
- if (context.count > context.limit) {
- results.push('...');
- return results;
- }
- results.push(this._decode(context, dimension + 1));
- }
- }
- if (context.shape.length == 0) {
- return results[0];
- }
- return results;
- }
- static _stringify(value, indentation, indent) {
- if (Array.isArray(value)) {
- const result = [];
- result.push(indentation + '[');
- const items = value.map((item) => paddle.Tensor._stringify(item, indentation + indent, indent));
- if (items.length > 0) {
- result.push(items.join(',\n'));
- }
- result.push(indentation + ']');
- return result.join('\n');
- }
- if (typeof value == 'string') {
- return indentation + value;
- }
- if (value == Infinity) {
- return indentation + 'Infinity';
- }
- if (value == -Infinity) {
- return indentation + '-Infinity';
- }
- if (isNaN(value)) {
- return indentation + 'NaN';
- }
- return indentation + value.toString();
- }
- };
- paddle.TensorType = class {
- constructor(dataType, shape) {
- this._dataType = dataType;
- this._shape = shape;
- }
- get dataType() {
- return this._dataType;
- }
- get shape() {
- return this._shape;
- }
- get denotation() {
- return this._denotation;
- }
- toString() {
- return this._dataType + this._shape.toString();
- }
- };
- paddle.TensorShape = class {
- constructor(dimensions) {
- dimensions = dimensions.map((dimension) => Number.isInteger(dimension) ? dimension : dimension.toNumber());
- this._dimensions = dimensions.map((dimension) => {
- return dimension != -1 ? dimension : '?';
- });
- }
- get dimensions() {
- return this._dimensions;
- }
- toString() {
- return (this._dimensions && this._dimensions.length) ? ('[' + this._dimensions.join(',') + ']') : '';
- }
- };
- paddle.Entries = class {
- static open(context) {
- const extension = [ 'zip', 'tar' ].find((extension) => context.entries(extension).size > 0);
- if (extension) {
- const entries = new Map(Array.from(context.entries(extension)).filter((entry) => !entry[0].endsWith('/') && !entry[0].split('/').pop().startsWith('.')).slice());
- if (entries.size > 2 && Array.from(entries).every((entry) => entry[0].split('_').length > 0 && entry[1].peek(16).every((value) => value === 0x00))) {
- return new paddle.Entries(entries);
- }
- }
- return null;
- }
- constructor(data) {
- this._data = data;
- }
- get format() {
- return 'PaddlePaddle Weights';
- }
- get weights() {
- this._read();
- return this._weights;
- }
- _read() {
- if (!this._weights) {
- let rootFolder = null;
- for (const entry of this._data) {
- const name = entry[0];
- if (!name.startsWith('.') || name.startsWith('./')) {
- const parts = name.split('/');
- const folder = ((parts.length > 2 && parts[0] === '.') ? ('./' + parts[1] + '/') : (parts.length > 1 ? parts[0] + '/' : ''));
- rootFolder = (rootFolder === null) ? folder : (rootFolder !== '' && folder !== rootFolder) ? '' : folder;
- }
- }
- this._weights = new Map();
- for (const entry of this._data) {
- if (entry[0].startsWith(rootFolder)) {
- const name = entry[0].substring(rootFolder.length);
- const stream = entry[1];
- const tensor = paddle.Utility.openTensorDesc(stream);
- this._weights.set(name, tensor);
- }
- }
- }
- }
- };
- paddle.Pickle = class {
- static open(context) {
- const obj = context.open('pkl');
- const container = new paddle.Pickle(obj);
- return container.weights !== null ? container : null;
- }
- constructor(obj) {
- this._weights = null;
- if (obj && !Array.isArray(obj) && (obj instanceof Map || Object(obj) === obj)) {
- const entries = (obj) => {
- return obj instanceof Map ? Array.from(obj) : Object(obj) === obj ? Object.entries(obj) : [];
- };
- const filter = (obj) => {
- const list = [];
- if (obj && !Array.isArray(obj)) {
- for (const entry of entries(obj)) {
- const name = entry[0];
- if (name !== 'StructuredToParameterName@@') {
- let value = entry[1];
- value = value && Array.isArray(value) && value.length === 2 && value[0] === name ? value[1] : value;
- if (value && !Array.isArray(value) && value.__class__ && value.__class__.__module__ === 'numpy' && value.__class__.__name__ === 'ndarray') {
- list.push([ name, value ]);
- }
- }
- }
- }
- return list;
- };
- const weights = filter(obj);
- if (weights.length > 0) {
- this._weights = weights;
- }
- else {
- const list = entries(obj);
- if (list.filter((entry) => entry[0] !== 'StructuredToParameterName@@').length === 1) {
- const weights = filter(list[0][1]);
- if (weights.length > 0) {
- this._weights = weights;
- }
- }
- if (this._weights === null && list.filter((entry) => entry[0] === 'StructuredToParameterName@@').length > 0) {
- this._weights = [];
- }
- }
- }
- }
- get format() {
- return 'PaddlePaddle Pickle';
- }
- get weights() {
- if (this._weights && Array.isArray(this._weights)) {
- const weights = new Map();
- for (const entry of this._weights) {
- const name = entry[0];
- const value = entry[1];
- const type = new paddle.TensorType(value.dtype.__name__, new paddle.TensorShape(value.shape));
- const data = value.data;
- const tensor = new paddle.Tensor(type, data, 'NumPy Array');
- weights.set(name, tensor);
- }
- this._weights = weights;
- }
- return this._weights;
- }
- };
- paddle.NaiveBuffer = class {
- static open(context) {
- const stream = context.stream;
- if (stream && stream.length > 4) {
- const buffer = stream.peek(4);
- if (context.identifier === '__model__.nb' || context.identifier === 'param.nb') {
- if (buffer[0] > 2 || buffer[1] !== 0x00 || buffer[2] !== 0x76 || buffer[2] !== 0x32) {
- return new paddle.NaiveBuffer(stream, -1);
- }
- }
- if (buffer[1] === 0x00 && buffer[0] <= 2) {
- return new paddle.NaiveBuffer(stream, buffer[0]);
- }
- }
- return null;
- }
- constructor(stream, meta_version) {
- this.stream = stream;
- this.meta_version = meta_version;
- }
- get format() {
- this._read();
- return this._format;
- }
- get model() {
- this._read();
- return this._model;
- }
- get weights() {
- this._read();
- return this._weights;
- }
- _read() {
- if (this.stream) {
- const reader = new base.BinaryReader(this.stream);
- if (this.meta_version >= 2) {
- reader.skip(2);
- }
- delete this.stream;
- const decoder = new TextDecoder();
- const opt_version = reader.read(16);
- const version = decoder.decode(opt_version.slice(0, opt_version.indexOf(0x00)));
- this._format = 'Paddle Lite' + (version ? ' ' + version : '');
- const topo_size = reader.uint64();
- const openProgramDesc = (buffer) => {
- const reader = flatbuffers.BinaryReader.open(buffer);
- return paddle.schema.ProgramDesc.create(reader);
- };
- const openParamDesc = (buffer) => {
- const reader = flatbuffers.BinaryReader.open(buffer);
- return paddle.schema.ParamDesc.create(reader);
- };
- switch (this.meta_version) {
- case -1: {
- throw new paddle.Error('Paddle Lite naive buffer format is deprecated.');
- }
- case 0:
- case 1: {
- throw new paddle.Error("Paddle Lite meta format '" + this.meta_version.toString() + "' is deprecated.");
- }
- case 2: {
- const topo_data = new Uint8Array(topo_size);
- topo_data.set(reader.read(topo_size), 0);
- this._model = openProgramDesc(topo_data);
- reader.uint16(); // version
- reader.uint16(); // meta_size
- const header_size = reader.uint16();
- const params_size = reader.uint16();
- reader.uint32(); // max_tensor_size
- reader.skip(header_size - 6);
- this._weights = new Map();
- for (let i = 0; i < params_size; i++) {
- const total_size = reader.uint32();
- const offset = reader.uint32();
- const param_bytes = total_size - offset;
- const param_data = reader.read(param_bytes);
- const desc = openParamDesc(param_data);
- const data = desc.variable.data;
- const data_type = desc.variable.data_type;
- const dim = desc.variable.dim;
- const type = paddle.Utility.createTensorType(data_type, dim);
- const tensor = new paddle.Tensor(type, data);
- this._weights.set(desc.name, tensor);
- }
- break;
- }
- default: {
- throw new paddle.Error("Unsupported Paddle Lite naive buffer meta format '" + this.meta_version.toString() + "'.");
- }
- }
- }
- }
- };
- paddle.Utility = class {
- static createTensorType(data_type, shape) {
- if (!paddle.Utility._dataTypes) {
- const length = Math.max.apply(null, Object.entries(paddle.DataType).map((entry) => entry[1]));
- paddle.Utility._dataTypes = new Array(length);
- const map = new Map([ [ 'bool', 'boolean' ], [ 'bf16', 'bfloat16' ], [ 'fp16', 'float16' ], [ 'fp32', 'float32' ], [ 'fp64', 'float64' ] ]);
- for (const entry of Object.entries(paddle.DataType)) {
- const index = entry[1];
- const key = entry[0].toLowerCase();
- paddle.Utility._dataTypes[index] = map.has(key) ? map.get(key) : key;
- }
- }
- const dataType = data_type < paddle.Utility._dataTypes.length ? paddle.Utility._dataTypes[data_type] : '?';
- return new paddle.TensorType(dataType, new paddle.TensorShape(shape));
- }
- static openTensorDesc(stream) {
- const signature = stream.read(16);
- if (!signature.every((value) => value === 0x00)) {
- throw new paddle.Error('Invalid paddle.TensorDesc signature.');
- }
- const length = new base.BinaryReader(stream.read(4)).uint32();
- const buffer = stream.read(length);
- const reader = protobuf.BinaryReader.open(buffer);
- const tensorDesc = paddle.proto.VarType.TensorDesc.decode(reader);
- const size = tensorDesc.dims.reduce((a, b) => a * b.toNumber(), 1);
- let itemsize = 0;
- switch (tensorDesc.data_type) {
- case paddle.DataType.FP16: itemsize = 2; break;
- case paddle.DataType.FP32: itemsize = 4; break;
- case paddle.DataType.FP64: itemsize = 8; break;
- case paddle.DataType.INT8: itemsize = 1; break;
- case paddle.DataType.INT16: itemsize = 2; break;
- case paddle.DataType.INT32: itemsize = 4; break;
- case paddle.DataType.INT64: itemsize = 8; break;
- case paddle.DataType.UINT8: itemsize = 1; break;
- default: throw new paddle.Error("Invalid inference params data type '" + tensorDesc.data_type + "'.");
- }
- const type = paddle.Utility.createTensorType(tensorDesc.data_type, tensorDesc.dims);
- const data = stream.read(itemsize * size);
- return new paddle.Tensor(type, data);
- }
- };
- paddle.DataType = {
- BOOL: 0,
- INT16: 1,
- INT32: 2,
- INT64: 3,
- FP16: 4,
- FP32: 5,
- FP64: 6,
- LOD_TENSOR: 7,
- SELECTED_ROWS: 8,
- FEED_MINIBATCH: 9,
- FETCH_LIST: 10,
- STEP_SCOPES: 11,
- LOD_RANK_TABLE: 12,
- LOD_TENSOR_ARRAY: 13,
- PLACE_LIST: 14,
- READER: 15,
- RAW: 17,
- TUPLE: 18,
- SIZE_T: 19,
- UINT8: 20,
- INT8: 21,
- BF16: 22,
- COMPLEX64: 23,
- COMPLEX128: 24,
- };
- paddle.AttributeType = {
- INT: 0,
- FLOAT: 1,
- STRING: 2,
- INTS: 3,
- FLOATS: 4,
- STRINGS: 5,
- BOOLEAN: 6,
- BOOLEANS: 7,
- BLOCK: 8,
- LONG: 9,
- BLOCKS: 10,
- LONGS: 11,
- FLOAT64S: 12
- };
- paddle.Error = class extends Error {
- constructor(message) {
- super(message);
- this.name = 'Error loading PaddlePaddle model.';
- }
- };
- if (typeof module !== 'undefined' && typeof module.exports === 'object') {
- module.exports.ModelFactory = paddle.ModelFactory;
- }
|