【Elasticsearch】-图片向量化存储

news2024/9/20 16:15:39

需要结合深度学习模型

1、pom依赖

注意结尾的webp-imageio 包,用于解决ImageIO.read读取部分图片返回为null的问题


        <dependency>
            <groupId>org.openpnp</groupId>
            <artifactId>opencv</artifactId>
            <version>4.7.0-0</version>
        </dependency>

        <dependency>
            <groupId>com.microsoft.onnxruntime</groupId>
            <artifactId>onnxruntime</artifactId>
            <version>1.17.1</version>
        </dependency>

        <!-- 服务器端推理引擎 -->
        <dependency>
            <groupId>ai.djl</groupId>
            <artifactId>api</artifactId>
            <version>${djl.version}</version>
        </dependency>
        <dependency>
            <groupId>ai.djl</groupId>
            <artifactId>basicdataset</artifactId>
            <version>${djl.version}</version>
        </dependency>
        <dependency>
            <groupId>ai.djl</groupId>
            <artifactId>model-zoo</artifactId>
            <version>${djl.version}</version>
        </dependency>
        <!-- Pytorch -->
        <dependency>
            <groupId>ai.djl.pytorch</groupId>
            <artifactId>pytorch-engine</artifactId>
            <version>${djl.version}</version>
        </dependency>
        <dependency>
            <groupId>ai.djl.pytorch</groupId>
            <artifactId>pytorch-model-zoo</artifactId>
            <version>${djl.version}</version>
        </dependency>
        <!-- ONNX -->
        <dependency>
            <groupId>ai.djl.onnxruntime</groupId>
            <artifactId>onnxruntime-engine</artifactId>
            <version>${djl.version}</version>
        </dependency>


        <!-- 解决ImageIO.read 读取为null -->
        <dependency>
            <groupId>org.sejda.imageio</groupId>
            <artifactId>webp-imageio</artifactId>
            <version>0.1.6</version>
        </dependency>

2、加载模型

注意提前设置环境变量,pytorch依赖环境dll文件,如果不存在,则默认下载

System.setProperty("ENGINE_CACHE_DIR", modelPath);

import ai.djl.Device;
import ai.djl.modality.cv.Image;
import ai.djl.repository.zoo.Criteria;
import ai.djl.training.util.ProgressBar;
import ai.djl.translate.Translator;

 public Criteria<Image, T> criteria() {
        Translator<Image, T> translator = getTranslator(arguments);
        try {
            JarFileUtils.copyFileFromJar("/onnx/models/" + modelName, PathConstants.ONNX, null, false, true);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
//        String model_path = PathConstants.TEMP_DIR + PathConstants.ONNX + "/" + modelName;
        String modelPath = PathConstants.TEMP_DIR + File.separator+PathConstants.ONNX_NAME+ File.separator + modelName;
        log.info("路径修改前:{}",modelPath);
        modelPath= DjlHandlerUtil.getFixedModelPath(modelPath);
        log.info("路径修改后:{}",modelPath);
        Criteria<Image, T> criteria =
                Criteria.builder()
                        .setTypes(Image.class, getClassOfT())
                        .optModelUrls(modelPath)
                        .optTranslator(translator)
                        .optDevice(Device.cpu())
                        .optEngine(getEngine()) // Use PyTorch engine
                        .optProgress(new ProgressBar())
                        .build();
        return criteria;
    }


protected Translator<Image, float[]> getTranslator(Map<String, Object> arguments) {
        BaseImageTranslator.BaseBuilder<?> builder=new BaseImageTranslator.BaseBuilder<BaseImageTranslator.BaseBuilder>() {
            @Override
            protected BaseImageTranslator.BaseBuilder self() {
                return this;
            }
        };
        return new BaseImageTranslator<float[]>(builder) {
            @Override
            public float[] processOutput(TranslatorContext translatorContext, NDList ndList) throws Exception {
                return ndList.get(0).toFloatArray();

            }
        };
    }

3、FaceFeatureTranslator



import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.transform.Normalize;
import ai.djl.modality.cv.transform.ToTensor;
import ai.djl.ndarray.NDArray;
import ai.djl.ndarray.NDList;
import ai.djl.translate.Batchifier;
import ai.djl.translate.Pipeline;
import ai.djl.translate.Translator;
import ai.djl.translate.TranslatorContext;

/**
 * @author gc.x
 * @date 2022-04
 */
public final class FaceFeatureTranslator implements Translator<Image, float[]> {

    public FaceFeatureTranslator() {
    }

    @Override
    public NDList processInput(TranslatorContext ctx, Image input) {
        NDArray array = input.toNDArray(ctx.getNDManager(), Image.Flag.COLOR);
        Pipeline pipeline = new Pipeline();
        pipeline
                // .add(new Resize(160))
                .add(new ToTensor())
                .add(
                        new Normalize(
                                new float[]{127.5f / 255.0f, 127.5f / 255.0f, 127.5f / 255.0f},
                                new float[]{128.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f}));

        return pipeline.transform(new NDList(array));
    }

    @Override
    public float[] processOutput(TranslatorContext ctx, NDList list) {
        NDList result = new NDList();
        long numOutputs = list.singletonOrThrow().getShape().get(0);
        for (int i = 0; i < numOutputs; i++) {
            result.add(list.singletonOrThrow().get(i));
        }
        float[][] embeddings = result.stream().map(NDArray::toFloatArray).toArray(float[][]::new);
        float[] feature = new float[embeddings.length];
        for (int i = 0; i < embeddings.length; i++) {
            feature[i] = embeddings[i][0];
        }
        return feature;
    }

    @Override
    public Batchifier getBatchifier() {
        return Batchifier.STACK;
    }
}

4、BaseImageTranslator


import ai.djl.Model;
import ai.djl.modality.cv.Image;
import ai.djl.modality.cv.transform.CenterCrop;
import ai.djl.modality.cv.transform.Normalize;
import ai.djl.modality.cv.transform.Resize;
import ai.djl.modality.cv.transform.ToTensor;
import ai.djl.modality.cv.util.NDImageUtils;
import ai.djl.ndarray.NDArray;
import ai.djl.ndarray.NDList;
import ai.djl.translate.*;
import ai.djl.util.Utils;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


public abstract class BaseImageTranslator<T> implements Translator<Image, T> {

    private static final float[] MEAN = {0.485f, 0.456f, 0.406f};
    private static final float[] STD = {0.229f, 0.224f, 0.225f};

    private Image.Flag flag;
    private Pipeline pipeline;
    private Batchifier batchifier;

    /**
     * Constructs an ImageTranslator with the provided builder.
     *
     * @param builder the data to build with
     */
    public BaseImageTranslator(BaseBuilder<?> builder) {
        flag = builder.flag;
        pipeline = builder.pipeline;
        batchifier = builder.batchifier;
    }

    /** {@inheritDoc} */
    @Override
    public Batchifier getBatchifier() {
        return batchifier;
    }

    /**
     * Processes the {@link Image} input and converts it to NDList.
     *
     * @param ctx the toolkit that helps create the input NDArray
     * @param input the {@link Image} input
     * @return a {@link NDList}
     */
    @Override
    public NDList processInput(TranslatorContext ctx, Image input) {
        NDArray array = input.toNDArray(ctx.getNDManager(), flag);
        array = NDImageUtils.resize(array, 640, 640);
        array = array.transpose(2, 0, 1); // HWC -> CHW RGB -> BGR
//        array = array.expandDims(0);
        array = array.div(255f);
        return new NDList(array);
//        return pipeline.transform(new NDList(array));
    }

    protected static String getStringValue(Map<String, ?> arguments, String key, String def) {
        Object value = arguments.get(key);
        if (value == null) {
            return def;
        }
        return value.toString();
    }

    protected static int getIntValue(Map<String, ?> arguments, String key, int def) {
        Object value = arguments.get(key);
        if (value == null) {
            return def;
        }
        return (int) Double.parseDouble(value.toString());
    }

    protected static float getFloatValue(Map<String, ?> arguments, String key, float def) {
        Object value = arguments.get(key);
        if (value == null) {
            return def;
        }
        return (float) Double.parseDouble(value.toString());
    }

    protected static boolean getBooleanValue(Map<String, ?> arguments, String key, boolean def) {
        Object value = arguments.get(key);
        if (value == null) {
            return def;
        }
        return Boolean.parseBoolean(value.toString());
    }

    /**
     * A builder to extend for all classes extending the {@link BaseImageTranslator}.
     *
     * @param <T> the concrete builder type
     */
    @SuppressWarnings("rawtypes")
    public abstract static class BaseBuilder<T extends BaseBuilder> {

        protected int width = 224;
        protected int height = 224;
        protected Image.Flag flag = Image.Flag.COLOR;
        protected Pipeline pipeline;
        protected Batchifier batchifier = Batchifier.STACK;

        /**
         * Sets the optional {@link Image.Flag} (default is {@link
         * Image.Flag#COLOR}).
         *
         * @param flag the color mode for the images
         * @return this builder
         */
        public T optFlag(Image.Flag flag) {
            this.flag = flag;
            return self();
        }

        /**
         * Sets the {@link Pipeline} to use for pre-processing the image.
         *
         * @param pipeline the pre-processing pipeline
         * @return this builder
         */
        public T setPipeline(Pipeline pipeline) {
            this.pipeline = pipeline;
            return self();
        }

        /**
         * Adds the {@link Transform} to the {@link Pipeline} use for pre-processing the image.
         *
         * @param transform the {@link Transform} to be added
         * @return this builder
         */
        public T addTransform(Transform transform) {
            if (pipeline == null) {
                pipeline = new Pipeline();
            }
            pipeline.add(transform);
            return self();
        }

        /**
         * Sets the {@link Batchifier} for the {@link Translator}.
         *
         * @param batchifier the {@link Batchifier} to be set
         * @return this builder
         */
        public T optBatchifier(Batchifier batchifier) {
            this.batchifier = batchifier;
            return self();
        }

        protected abstract T self();

        protected void validate() {
            if (pipeline == null) {
                throw new IllegalArgumentException("pipeline is required.");
            }
        }

        protected void configPreProcess(Map<String, ?> arguments) {
            if (pipeline == null) {
                pipeline = new Pipeline();
            }
            width = getIntValue(arguments, "width", 224);
            height = getIntValue(arguments, "height", 224);
            if (arguments.containsKey("flag")) {
                flag = Image.Flag.valueOf(arguments.get("flag").toString());
            }
            if (getBooleanValue(arguments, "centerCrop", false)) {
                addTransform(new CenterCrop());
            }
            if (getBooleanValue(arguments, "resize", false)) {
                addTransform(new Resize(width, height));
            }
            if (getBooleanValue(arguments, "toTensor", true)) {
                addTransform(new ToTensor());
            }
            String normalize = getStringValue(arguments, "normalize", "false");
            if ("true".equals(normalize)) {
                addTransform(new Normalize(MEAN, STD));
            } else if (!"false".equals(normalize)) {
                String[] tokens = normalize.split("\\s*,\\s*");
                if (tokens.length != 6) {
                    throw new IllegalArgumentException("Invalid normalize value: " + normalize);
                }
                float[] mean = {
                    Float.parseFloat(tokens[0]),
                    Float.parseFloat(tokens[1]),
                    Float.parseFloat(tokens[2])
                };
                float[] std = {
                    Float.parseFloat(tokens[3]),
                    Float.parseFloat(tokens[4]),
                    Float.parseFloat(tokens[5])
                };
                addTransform(new Normalize(mean, std));
            }
            String range = (String) arguments.get("range");
            if ("0,1".equals(range)) {
                addTransform(a -> a.div(255f));
            } else if ("-1,1".equals(range)) {
                addTransform(a -> a.div(128f).sub(1));
            }
            if (arguments.containsKey("batchifier")) {
                batchifier = Batchifier.fromString((String) arguments.get("batchifier"));
            }
        }

        protected void configPostProcess(Map<String, ?> arguments) {}
    }

    /** A Builder to construct a {@code ImageClassificationTranslator}. */
    @SuppressWarnings("rawtypes")
    public abstract static class ClassificationBuilder<T extends BaseBuilder>
            extends BaseBuilder<T> {

        protected SynsetLoader synsetLoader;

        /**
         * Sets the name of the synset file listing the potential classes for an image.
         *
         * @param synsetArtifactName a file listing the potential classes for an image
         * @return the builder
         */
        public T optSynsetArtifactName(String synsetArtifactName) {
            synsetLoader = new SynsetLoader(synsetArtifactName);
            return self();
        }

        /**
         * Sets the URL of the synset file.
         *
         * @param synsetUrl the URL of the synset file
         * @return the builder
         */
        public T optSynsetUrl(String synsetUrl) {
            try {
                this.synsetLoader = new SynsetLoader(new URL(synsetUrl));
            } catch (MalformedURLException e) {
                throw new IllegalArgumentException("Invalid synsetUrl: " + synsetUrl, e);
            }
            return self();
        }

        /**
         * Sets the potential classes for an image.
         *
         * @param synset the potential classes for an image
         * @return the builder
         */
        public T optSynset(List<String> synset) {
            synsetLoader = new SynsetLoader(synset);
            return self();
        }

        /** {@inheritDoc} */
        @Override
        protected void validate() {
            super.validate();
            if (synsetLoader == null) {
                synsetLoader = new SynsetLoader("synset.txt");
            }
        }

        /** {@inheritDoc} */
        @Override
        protected void configPostProcess(Map<String, ?> arguments) {
            String synset = (String) arguments.get("synset");
            if (synset != null) {
                optSynset(Arrays.asList(synset.split(",")));
            }
            String synsetUrl = (String) arguments.get("synsetUrl");
            if (synsetUrl != null) {
                optSynsetUrl(synsetUrl);
            }
            String synsetFileName = (String) arguments.get("synsetFileName");
            if (synsetFileName != null) {
                optSynsetArtifactName(synsetFileName);
            }
        }
    }

    protected static final class SynsetLoader {

        private String synsetFileName;
        private URL synsetUrl;
        private List<String> synset;

        public SynsetLoader(List<String> synset) {
            this.synset = synset;
        }

        public SynsetLoader(URL synsetUrl) {
            this.synsetUrl = synsetUrl;
        }

        public SynsetLoader(String synsetFileName) {
            this.synsetFileName = synsetFileName;
        }

        public List<String> load(Model model) throws IOException {
            if (synset != null) {
                return synset;
            } else if (synsetUrl != null) {
                try (InputStream is = synsetUrl.openStream()) {
                    return Utils.readLines(is);
                }
            }
            return model.getArtifact(synsetFileName, Utils::readLines);
        }
    }
}

5、创建向量索引字段

需要在索引库创建的时候,一并创建对应字段。

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.mapping.Property;
import co.elastic.clients.elasticsearch._types.mapping.TypeMapping;
import co.elastic.clients.elasticsearch.indices.Alias;
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import co.elastic.clients.elasticsearch.indices.ExistsRequest;


CreateIndexResponse response = null;
        try {

            TypeMapping.Builder tmBuilder = new TypeMapping.Builder();
            // 图片相似检索,采用点积运算  文本相似采用余线相似
            tmBuilder.properties('_img_vector', new Property.Builder().denseVector(builder -> builder.index(true).dims(1024).similarity("dot_product")
                    .indexOptions(opBuilder -> opBuilder.type("hnsw").m(12).efConstruction(100))).build());

            TypeMapping typeMapping = tmBuilder.build();

            CreateIndexRequest request = CreateIndexRequest.of(builder -> builder.index(indexName)
                    .aliases(indexName + "_alias", new Alias.Builder().isWriteIndex(true).build())
                    .mappings(typeMapping));

            response = esClient.indices().create(request);

            log.info("acknowledged: {}", response.acknowledged());
            log.info("index: {}", response.index());
            log.info("shardsAcknowledged: {}", response.shardsAcknowledged());

            flag = response.acknowledged();
        } catch (IOException e) {
            e.printStackTrace();
        }

创建后生成的结构数据如下

 

6、添加到ES

float[] feature;
// 自定义属性字段数据,构建文档
            Map<String, Object> dataMap = req.getDataMap();
            // 自定义内置参数
            dataMap.put("_es_doc_type", "IMAGE");

            dataMap.put("_img_vector", feature);
            IndexRequest<Map> request = IndexRequest.of(i -> i
                    .index(req.getIndexLib())
                    .id(req.getDocId())
                    .document(dataMap)
            );
            IndexResponse response = esClient.index(request);
            boolean flag = response.result() == Result.Created;
            log.info("添加文档id={},结果={}", req.getDocId(), flag);

实际存储的数据结构如下图

7、pytorch环境依赖

cpu/linux-x86_64/native/lib/libc10.so.gz
cpu/linux-x86_64/native/lib/libtorch_cpu.so.gz
cpu/linux-x86_64/native/lib/libtorch.so.gz
cpu/linux-x86_64/native/lib/libgomp-52f2fd74.so.1.gz
cpu/osx-aarch64/native/lib/libtorch_cpu.dylib.gz
cpu/osx-aarch64/native/lib/libtorch.dylib.gz
cpu/osx-aarch64/native/lib/libc10.dylib.gz
cpu/osx-x86_64/native/lib/libtorch_cpu.dylib.gz
cpu/osx-x86_64/native/lib/libiomp5.dylib.gz
cpu/osx-x86_64/native/lib/libtorch.dylib.gz
cpu/osx-x86_64/native/lib/libc10.dylib.gz
cpu/win-x86_64/native/lib/torch.dll.gz
cpu/win-x86_64/native/lib/uv.dll.gz
cpu/win-x86_64/native/lib/torch_cpu.dll.gz
cpu/win-x86_64/native/lib/c10.dll.gz
cpu/win-x86_64/native/lib/fbgemm.dll.gz
cpu/win-x86_64/native/lib/libiomp5md.dll.gz
cpu/win-x86_64/native/lib/asmjit.dll.gz
cpu/win-x86_64/native/lib/libiompstubs5md.dll.gz
cpu-precxx11/linux-aarch64/native/lib/libc10.so.gz
cpu-precxx11/linux-aarch64/native/lib/libtorch_cpu.so.gz
cpu-precxx11/linux-aarch64/native/lib/libarm_compute-973e5a6b.so.gz
cpu-precxx11/linux-aarch64/native/lib/libopenblasp-r0-56e95da7.3.24.so.gz
cpu-precxx11/linux-aarch64/native/lib/libtorch.so.gz
cpu-precxx11/linux-aarch64/native/lib/libarm_compute_graph-6990f339.so.gz
cpu-precxx11/linux-aarch64/native/lib/libstdc%2B%2B.so.6.gz
cpu-precxx11/linux-aarch64/native/lib/libarm_compute_core-0793f69d.so.gz
cpu-precxx11/linux-aarch64/native/lib/libgfortran-b6d57c85.so.5.0.0.gz
cpu-precxx11/linux-aarch64/native/lib/libgomp-6e1a1d1b.so.1.0.0.gz
cpu-precxx11/linux-x86_64/native/lib/libgomp-a34b3233.so.1.gz
cpu-precxx11/linux-x86_64/native/lib/libc10.so.gz
cpu-precxx11/linux-x86_64/native/lib/libtorch_cpu.so.gz
cpu-precxx11/linux-x86_64/native/lib/libtorch.so.gz
cpu-precxx11/linux-x86_64/native/lib/libstdc%2B%2B.so.6.gz
cu121/linux-x86_64/native/lib/libc10_cuda.so.gz
cu121/linux-x86_64/native/lib/libcudnn.so.8.gz
cu121/linux-x86_64/native/lib/libnvfuser_codegen.so.gz
cu121/linux-x86_64/native/lib/libc10.so.gz
cu121/linux-x86_64/native/lib/libtorch_cpu.so.gz
cu121/linux-x86_64/native/lib/libcaffe2_nvrtc.so.gz
cu121/linux-x86_64/native/lib/libcudnn_adv_infer.so.8.gz
cu121/linux-x86_64/native/lib/libcudnn_cnn_train.so.8.gz
cu121/linux-x86_64/native/lib/libcudnn_ops_infer.so.8.gz
cu121/linux-x86_64/native/lib/libnvrtc-builtins-6c5639ce.so.12.1.gz
cu121/linux-x86_64/native/lib/libnvrtc-b51b459d.so.12.gz
cu121/linux-x86_64/native/lib/libtorch.so.gz
cu121/linux-x86_64/native/lib/libtorch_cuda_linalg.so.gz
cu121/linux-x86_64/native/lib/libcublas-37d11411.so.12.gz
cu121/linux-x86_64/native/lib/libtorch_cuda.so.gz
cu121/linux-x86_64/native/lib/libcudnn_adv_train.so.8.gz
cu121/linux-x86_64/native/lib/libcublasLt-f97bfc2c.so.12.gz
cu121/linux-x86_64/native/lib/libnvToolsExt-847d78f2.so.1.gz
cu121/linux-x86_64/native/lib/libcudnn_ops_train.so.8.gz
cu121/linux-x86_64/native/lib/libcudnn_cnn_infer.so.8.gz
cu121/linux-x86_64/native/lib/libgomp-52f2fd74.so.1.gz
cu121/linux-x86_64/native/lib/libcudart-9335f6a2.so.12.gz
cu121/win-x86_64/native/lib/zlibwapi.dll.gz
cu121/win-x86_64/native/lib/cudnn_ops_train64_8.dll.gz
cu121/win-x86_64/native/lib/torch.dll.gz
cu121/win-x86_64/native/lib/nvrtc-builtins64_121.dll.gz
cu121/win-x86_64/native/lib/cufftw64_11.dll.gz
cu121/win-x86_64/native/lib/cudnn_adv_infer64_8.dll.gz
cu121/win-x86_64/native/lib/nvrtc64_120_0.dll.gz
cu121/win-x86_64/native/lib/cusolverMg64_11.dll.gz
cu121/win-x86_64/native/lib/torch_cuda.dll.gz
cu121/win-x86_64/native/lib/cufft64_11.dll.gz
cu121/win-x86_64/native/lib/cublas64_12.dll.gz
cu121/win-x86_64/native/lib/cudnn64_8.dll.gz
cu121/win-x86_64/native/lib/uv.dll.gz
cu121/win-x86_64/native/lib/cudnn_cnn_train64_8.dll.gz
cu121/win-x86_64/native/lib/caffe2_nvrtc.dll.gz
cu121/win-x86_64/native/lib/torch_cpu.dll.gz
cu121/win-x86_64/native/lib/c10.dll.gz
cu121/win-x86_64/native/lib/cudnn_cnn_infer64_8.dll.gz
cu121/win-x86_64/native/lib/c10_cuda.dll.gz
cu121/win-x86_64/native/lib/cudart64_12.dll.gz
cu121/win-x86_64/native/lib/nvfuser_codegen.dll.gz
cu121/win-x86_64/native/lib/fbgemm.dll.gz
cu121/win-x86_64/native/lib/curand64_10.dll.gz
cu121/win-x86_64/native/lib/libiomp5md.dll.gz
cu121/win-x86_64/native/lib/cusolver64_11.dll.gz
cu121/win-x86_64/native/lib/cudnn_adv_train64_8.dll.gz
cu121/win-x86_64/native/lib/cublasLt64_12.dll.gz
cu121/win-x86_64/native/lib/nvToolsExt64_1.dll.gz
cu121/win-x86_64/native/lib/nvJitLink_120_0.dll.gz
cu121/win-x86_64/native/lib/cusparse64_12.dll.gz
cu121/win-x86_64/native/lib/asmjit.dll.gz
cu121/win-x86_64/native/lib/cudnn_ops_infer64_8.dll.gz
cu121/win-x86_64/native/lib/libiompstubs5md.dll.gz
cu121/win-x86_64/native/lib/cupti64_2023.1.1.dll.gz
cu121-precxx11/linux-x86_64/native/lib/libgomp-a34b3233.so.1.gz
cu121-precxx11/linux-x86_64/native/lib/libc10_cuda.so.gz
cu121-precxx11/linux-x86_64/native/lib/libcudnn.so.8.gz
cu121-precxx11/linux-x86_64/native/lib/libnvfuser_codegen.so.gz
cu121-precxx11/linux-x86_64/native/lib/libc10.so.gz
cu121-precxx11/linux-x86_64/native/lib/libtorch_cpu.so.gz
cu121-precxx11/linux-x86_64/native/lib/libcaffe2_nvrtc.so.gz
cu121-precxx11/linux-x86_64/native/lib/libcudnn_adv_infer.so.8.gz
cu121-precxx11/linux-x86_64/native/lib/libcudnn_cnn_train.so.8.gz
cu121-precxx11/linux-x86_64/native/lib/libcudnn_ops_infer.so.8.gz
cu121-precxx11/linux-x86_64/native/lib/libnvrtc-builtins-6c5639ce.so.12.1.gz
cu121-precxx11/linux-x86_64/native/lib/libnvrtc-b51b459d.so.12.gz
cu121-precxx11/linux-x86_64/native/lib/libtorch.so.gz
cu121-precxx11/linux-x86_64/native/lib/libtorch_cuda_linalg.so.gz
cu121-precxx11/linux-x86_64/native/lib/libcublas-37d11411.so.12.gz
cu121-precxx11/linux-x86_64/native/lib/libtorch_cuda.so.gz
cu121-precxx11/linux-x86_64/native/lib/libstdc%2B%2B.so.6.gz
cu121-precxx11/linux-x86_64/native/lib/libcudnn_adv_train.so.8.gz
cu121-precxx11/linux-x86_64/native/lib/libcublasLt-f97bfc2c.so.12.gz
cu121-precxx11/linux-x86_64/native/lib/libnvToolsExt-847d78f2.so.1.gz
cu121-precxx11/linux-x86_64/native/lib/libcudnn_ops_train.so.8.gz
cu121-precxx11/linux-x86_64/native/lib/libcudnn_cnn_infer.so.8.gz
cu121-precxx11/linux-x86_64/native/lib/libcudart-9335f6a2.so.12.gz
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2149379.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【2025】中医药健康管理小程序(安卓原生开发+用户+管理员)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

海报制作哪个软件好?这些在线工具不容错过

国庆节的脚步越来越近&#xff0c;不少公司正计划利用这个时机开展一些特别的庆典活动。 在这些活动中&#xff0c;海报作为一种传统的宣传方式&#xff0c;仍然是不可或缺的。但在制作海报时&#xff0c;我们可能会遇到创意瓶颈、时间限制或者预算约束等问题。 幸运的是&…

高棉语翻译神器上线!中柬互译,OCR识别,语音翻译一应俱全,《柬埔寨语翻译通》App

全新的高棉语翻译神器已经正式上架&#xff01; 无论你是安卓还是iOS用户&#xff0c;现在都可以轻松开始使用&#xff0c;开启你的翻译之旅&#xff01; 这款应用不仅仅是一个简单的翻译工具&#xff0c;它还支持中文与高棉语的双向翻译。翻译结果可以语音播放&#xff0c;翻…

AI服务器是什么?为什么要用AI服务器?

AI服务器的定义 AI服务器是一种专门为人工智能应用设计的服务器&#xff0c;它采用异构形式的硬件架构&#xff0c;通常搭载GPU、FPGA、ASIC等加速芯片&#xff0c;利用CPU与加速芯片的组合来满足高吞吐量互联的需求&#xff0c;为自然语言处理、计算机视觉、机器学习等人工智…

企业微信-前往服务商后台页面对接解决方案

序 我会告诉你在哪里点我会告诉你在哪里配置点下去他只返回auth_code的&#xff0c;我怎么登录 正文 他是在这个位置 是这样&#xff0c;应用授权安装第三方应用后&#xff0c;企业微信&#xff08;管理员角色&#xff09;是可以从pc端企业后台点第三方应用的。 如果我没记…

【余弦相似度】

余弦相似度 又称为余弦距离&#xff0c;利用两个向量之间的夹角的余弦值来衡量两个向量的余弦相似度&#xff0c;两个向量夹角越小&#xff0c;余弦值越接近1。 向量模&#xff08;向量长度&#xff09;计算方法&#xff1a; n维向量的相似度计算&#xff1a; 余弦相似度的取…

黑盒测试 | 挖掘.NET程序中的反序列化漏洞

通过不安全反序列化漏洞远程执行代码 img 今天&#xff0c;我将回顾 OWASP 的十大漏洞之一&#xff1a;不安全反序列化&#xff0c;重点是 .NET 应用程序上反序列化漏洞的利用。 &#x1f4dd;$ _序列化_与_反序列化 序列化是将数据对象转换为字节流的过程&#xff0c;字节流…

Entity更新坐标不闪烁需采用setCallbackPositions方法赋值

问题描述&#xff1a; 1.new mars3d.graphic.PolygonEntity({在更新点位高度模拟水面上身的时候&#xff0c;会存在闪烁 2.当把addDemoGraphic4添加到图层后&#xff0c;addDemoGraphic1水位变化不闪烁&#xff0c;把addDemoGraphic4注释后&#xff0c;addDemoGraphic1闪烁。…

UI自动化测试的边界怎么定义?

标题&#xff1a;定义UI自动化测试的边界&#xff1a;从0到1的详细指南 引言&#xff1a; UI自动化测试是现代软件开发过程中至关重要的一环。为了确保自动化测试的有效性和准确性&#xff0c;我们需要明确定义测试的边界。本文将从0到1为您提供一篇详细且规范的指南&#xf…

基于YOLOv8/YOLOv9/YOLOv10的河道漂浮物检测识别系统

摘要&#xff1a; 河道漂浮物检测识别是指利用技术手段自动识别河流、湖泊等水体表面的漂浮垃圾或物体的过程。随着环境保护意识的增强和技术的进步&#xff0c;河道漂浮物检测已经成为水环境保护和管理的重要组成部分。这项技术的应用可以帮助及时发现污染源&#xff0c;采取措…

一些线上常用排查问题的命令

排查CPU过高时使用到的一些命令 top free df top命令 top 命令是一个动态的实时视图&#xff0c;显示系统的整体运行状况&#xff0c;包括 CPU 使用率、内存使用情况、进程信息等。 free 命令 free 命令用于显示系统中物理内存和交换内存的使用情况。 df 命令 df 命令用…

纯前端表格导出Excel

先写好两个js文件 直接复制粘贴 文件目录是这样的 Bolb.js /* eslint-disable */ /* Blob.js* A Blob implementation.* 2014-05-27** By Eli Grey, http://eligrey.com* By Devin Samarin, https://github.com/eboyjr* License: X11/MIT* See LICENSE.md*//*global self, …

Vuex 入门与实战

引言 Vuex 是 Vue.js 官方推荐的状态管理库&#xff0c;它可以帮助我们更好地管理 Vue 应用的状态。在大型应用中&#xff0c;组件之间的状态共享和通信是一个非常重要的问题&#xff0c;而 Vuex 提供了一种优雅的解决方案。 在 Vue 应用中&#xff0c;数据的流动一般是单向的…

PCA贡献率

什么是 PCA&#xff1f; PCA&#xff08;Principal Component Analysis, 主成分分析&#xff09;是一种常用的数据降维技术。它通过找到一组新的互不相关的正交轴&#xff08;主成分&#xff09;&#xff0c;将高维数据映射到低维空间。这些新轴是按照数据的方差大小排列的&am…

让Tkinter更美观:教你同步Tkinter窗口与弹窗图标(Tkinter同步主窗口与Messagebox的图标)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 步骤1:主窗口图标📝 步骤2:messagebox 图标📝 示例代码📝 实现原理与代码解释⚓️ 相关链接 ⚓️📖 介绍 📖 你有没有注意到,在开发软件图形界面时,会需要弹出一些提示框,而这些提示框的图标总…

阿里国际发布最新版多模态大模型Ovis,拿下开源第一

看一眼菜品图就知道怎么做、能给植物看病、能把手写英文准确翻译成中文、还能精准分析财报数据……多模态能力再次升级&#xff01;阿里国际AI团队发布了一款多模态大模型Ovis&#xff0c;在图像理解任务上不断突破极限&#xff0c;多种具体的子类任务中均达到了SOTA&#xff0…

【Linux】-----进程第一弹

目录 概念 描述进程-PCB 查看进程 获取进程标识符 终止进程 fork创建进程 返回值说明 进程的状态 ①运行状态(R) ②浅度睡眠(S) ③深度睡眠(D) ④暂停状态(T) ⑤僵尸状态(Z)(重点) 是什么&#xff1f; 举例 危害 孤儿进程 ⑥死亡状态(X) 概念 课本上对于进程…

如何保护电脑文件夹?多种方法保护数据安全

在数字化时代&#xff0c;电脑中的文件夹往往存储着我们最私密、最重要的数据&#xff0c;如个人文档、照片、工作资料等。因此&#xff0c;保护这些文件夹免受未经授权的访问、盗窃或损坏变得尤为重要。本文将介绍多种方法来有效保护电脑文件夹及其数据安全。 文件夹保护3000 …

MySQL中的比较条件

符号!也能够表示不等于条件。 示例一&#xff1a;查询employees表中员工薪水大于等于3000的员工的姓名与薪水。 select l ast_name,salary from employees where salary > 3000; 示例二&#xff1a;查询employees表中员工薪水不等于5000的员工的姓名与薪水。 select las…

人工智能在肿瘤浸润淋巴细胞研究中的最新进展|文献速递·24-09-20

小罗碎碎念 文献速递&#xff5c;目录 一、胆道癌治疗应答的新型AI生物标志物&#xff1a;肿瘤浸润性淋巴细胞的空间分布 补充文献&#xff1a;22年发表于JCO的一篇类似文献 二、生物标志物在肝细胞癌管理中的作用&#xff1a;从发现到临床应用 三、肿瘤样本中免疫细胞浸润水…