File size: 5,495 Bytes
9f613b3
 
6d312fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75e5313
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d312fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75e5313
 
6d312fd
 
 
 
 
 
 
75e5313
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        font-family: Arial, sans-serif;
      }
      input, button, progress {
        display: block;
        margin-top: 10px;
      }
      #message {
        margin-top: 20px;
        color: blue;
      }
      #error {
        color: red;
      }
    </style>
  </head>
  <body>
    <label for="tokenInput">Hugging Face Token:</label>
    <input type="password" id="tokenInput" name="tokenInput">
    <label for="repoInput">Repository ID:</label>
    <input type="text" id="repoInput" name="repoInput" placeholder="my-user/nlp-model">
    <input type="file" id="fileUpload" multiple>
    <button id="uploadButton">Upload Files</button>
    <div id="processingMessage"></div>
    <progress id="progressBar" value="0" max="100"></progress>
    <div id="message"></div>
    <div id="error"></div>

    <script type="module">
      import { createRepo, uploadFiles } from "https://cdn.jsdelivr.net/npm/@huggingface/[email protected]/+esm";

      const uploadButton = document.getElementById('uploadButton');
      uploadButton.addEventListener('click', upload);

      async function upload() {
        const fileInput = document.getElementById('fileUpload');
        const files = Array.from(fileInput.files); // convert FileList to Array
        const tokenInput = document.getElementById('tokenInput');
        const HF_ACCESS_TOKEN = tokenInput.value; // get the entered token
        const repoInput = document.getElementById('repoInput');
        const REPO_ID = repoInput.value; // get the entered repo id
        const progressBar = document.getElementById('progressBar');
        const messageDiv = document.getElementById('message');
        const errorDiv = document.getElementById('error');
        const processingMessage = document.getElementById('processingMessage');
        progressBar.value = 0; // reset progress bar
        messageDiv.textContent = ''; // clear previous messages
        errorDiv.textContent = ''; // clear previous errors
        processingMessage.textContent = ''; // clear previous processing message

        if (files.length > 0) {
          // calculate total size in MB
          let totalSize = 0;
          for (let file of files) {
            totalSize += file.size;
          }
          totalSize = totalSize / (1024 * 1024); // convert to MB

          // start time
          const startTime = Date.now();

          try {
            // Attempt to create the repo
            await createRepo({
              repo: REPO_ID,
              credentials: { accessToken: HF_ACCESS_TOKEN },
            });
          } catch (error) {
            // If the repo already exists, we simply log and continue
            if (error.message === 'You already created this model repo') {
              console.log('Repository already exists, proceeding to upload files');
            } else {
              console.error('Error creating repository', error);
              errorDiv.textContent = 'Error creating repository';
              return; // stop if other errors occur during repository creation
            }
          }

          try {
            // upload files in chunks
            for (let file of files) {
              const chunkSize = 1024 * 1024; // 1MB
              let start = 0;
              let end = chunkSize;
              let index = 0;

              while (start < file.size) {
                const chunk = file.slice(start, end);
                chunk.name = `${file.name}.chunk${index}`; // chunk naming convention
                start = end;
                end = start + chunkSize;
                index++;

                await uploadFiles({
                  repo: REPO_ID,
                  credentials: { accessToken: HF_ACCESS_TOKEN },
                  files: [{ path: chunk.name, content: chunk }],
                });

                // update progress bar
                progressBar.value = (start / file.size) * 100;
              }
            }

            console.log(`All files uploaded successfully`);

            // update progress bar
            progressBar.value = 100;
          } catch (error) {
            console.error('Error uploading files', error);
            errorDiv.textContent = 'Error uploading files';
            return; // stop uploading further files on error
          }

          // calculate elapsed time and speed
          const elapsedTime = (Date.now() - startTime) / 1000; // in seconds
          let speed = totalSize / elapsedTime; // in MB/s

          // Estimate time to upload larger files in minutes
          let time1GB = (1024 / speed) / 60;
          let time5GB = (5 * 1024 / speed) / 60;
          let time10GB = (10 * 1024 / speed) / 60;

          // Update the message with upload statistics
          messageDiv.innerHTML = `All files uploaded successfully in ${elapsedTime.toFixed(2)} seconds, for all ${totalSize.toFixed(2)} MB in the ${files.length} files, speed ${speed.toFixed(2)} MB/s. <br> To upload a 1GB model at this speed, it would take approximately ${time1GB.toFixed(2)} minutes. <br> To upload a 5GB model at this speed, it would take approximately ${time5GB.toFixed(2)} minutes. <br> To upload a 10GB model at this speed, it would take approximately ${time10GB.toFixed(2)} minutes.`;
          processingMessage.textContent = "All files processed";
        } else {
          messageDiv.textContent = 'Please select files to upload';
        }
      }
    </script>
  </body>
</html>